2014-10-06 4 views
0

Я довольно новичок в тестировании Rspec, и это очень расстраивает.Rspec тестирование validates_uniqueness_of проходит, когда он должен потерпеть неудачу

У меня есть модель, которая использует 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

Вы говорите, что оно проходит, когда оно должно потерпеть неудачу, но вы показываете сбой? –

ответ

1

Я думаю (не могу проверить себя сейчас), что subject не выполнен в вашем тесте. Попробуйте этот вариант

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

Это сделало тест! Но я понятия не имею, почему ... Я думал, что объект * join * будет видимым внутри теста «должен быть уникальным», потому что он был объявлен в начале. – Adam

+0

«видимый» и «исполненный» - это разные вещи. 'subject',' let' имеют «ленивую» стратегию загрузки. Если он не вызывается - он не выполняется. идея описана [здесь] (https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and-let) – gotva

+0

Ах! Конечно! Я забыл о ленивой загрузке. Итак, другое решение - использовать * let! * Вместо * let *. Спасибо. – Adam

Смежные вопросы