2014-10-06 157 views
0

我对Rspec测试相当陌生,这非常令人沮丧。当它失败时,validates_uniqueness_of的Rspec测试通过

我有一个模型,它使用validates_uniqueness_of来防止重复条目被创建。 (我知道这是不能保证的,首选的方法是使用数据库级别的约束,但目前不相关)。

问题是,我的Rspec测试似乎表明,即使在实践中,在控制台和应用程序本身中,这也无法完成,但可以在表中创建2个具有相同user_id和board_id的条目。

型号/ moderator_join.rb

class ModeratorJoin < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :board 

    validates :user_id, presence: true 
    validates :board_id, presence: true 

    validates_uniqueness_of :user_id, scope: :board_id, message: "is already a moderator of that board." 
end 

规格/型号/ moderator_join_spec.rb

describe ModeratorJoin do 
    let(:user) { create(:user) } // Create with FactoryGirl 
    let(:board) { create(:board) } // Create with FactoryGirl 
    let(:join) { ModeratorJoin.create(user: user, board: board) } 

    subject { join } 

    it { should be_valid } // Test passes 
    its(:id) { should_not eq nil } // Test passes 
    its(:user) { should eq user } // Test passes 
    its(:board) { should eq board } // Test passes 

    describe "user/board pairs" do 
    let(:join2) { ModeratorJoin.new(user: user, board: board) } 

    it "must be unique" do 
     expect(join2).to_not be_valid // TEST FAILS 
    end 
    end 
end 

控制台输出

Failures: 
1) ModeratorJoin user/board pairs must be unique 
Failure/Error: expect(join2).to_not be_valid 
expected #<ModeratorJoin id: nil, user_id: 121, board_id: 1, created_at: nil, updated_at: nil> not to be valid 

# ./spec/models/moderator_join_spec.rb:39:in `block (3 levels) in <top (required)>' 
+0

你说它通过时,它应该失败,但你显示失败? – 2014-10-06 18:43:25

回答

1

我认为(现在不能检查自己)subject没有在您的测试中执行。尝试这个变体

it "must be unique" do 
    subject 
    expect(join2).to_not be_valid // TEST FAILS 
end 
+0

这使测试通过!但我不知道为什么......我认为* join *对象在“must be unique”测试中是可见的,因为它是在开始时声明的。 – Adam 2014-10-06 18:59:22

+0

“可见”和“执行”是不同的东西。 'subject','let'有“懒惰”的加载策略。如果它没有被调用 - 它不会被执行。想法被描述[这里](https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and-let) – gotva 2014-10-06 19:03:46

+0

啊!当然!我忘记了延迟加载。所以,另一种解决方案是使用* let!*而不是* let *。谢谢。 – Adam 2014-10-06 19:08:05