1

Я хотел бы протестировать uniquness модели пользователя.rspec mongoid проверка уникальности

Моя User модель класса выглядит следующим образом:

class User 
    include Mongoid::Document 
    field :email, type: String 
    embeds_one :details 

    validates :email, 
     presence: true, 
     uniqueness: true, 
     format: { 
     with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z0-9]{2,})\Z/i, 
     on: :create 
     }, 
     length: { in: 6..50 } 

end 

Мой RSpec тест, который относится к модели выглядит следующим образом:

... 
before(:each) do 
    FactoryGirl.create(:user, email: taken_mail) 
end 

it "with an already used email" do 
    expect(FactoryGirl.create(:user, email: taken_mail)).to_not be_valid 
end 

После я выполнил bundle exec rspec это всегда вызывает следующую ошибку вместо того, чтобы прошло с успех:

Failure/Error: expect(FactoryGirl.create(:user, email: taken_mail)).to_not be_valid 
    Mongoid::Errors::Validations: 

     Problem: 
     Validation of User failed. 
     Summary: 
     The following errors were found: Email is already taken 
     Resolution: 
     Try persisting the document with valid data or remove the validations. 

Если я использую этот она проходит с успехом:

it { should validate_uniqueness_of(:email) } 

Я хотел бы использовать expect(...). Кто-нибудь может мне помочь?

+1

Что делать, если вы попробуете: 'ожидать (FactoryGirl.build (: user, email: taken_mail)). To_not be_valid'? используя сборку вместо создания – Alireza

+0

Он работает правильно, и тесты прошли, но я не знаю, почему возникает ошибка при использовании метода 'create'. Что делать, если я хочу использовать 'FactoryGirl.create (...)' Если вы оставите это в ответе, я дам вам точку. – Mark

ответ

1

Проблема заключается в том, что вы пытаетесь сохранить недопустимый объект в базе данных, что создает исключение и прерывает проверку (поскольку электронная почта не уникальна), прежде чем даже тест выполняется с использованием метода expect.

Правильный способ заключается в использовании build здесь, а не create, который не сохраняет объект в базе данных, создавая запись только в памяти и позволяя вашему тесту выполнять свою работу. Поэтому, чтобы исправить это:

expect(FactoryGirl.build(:user, email: taken_mail)).to_not be_valid 

Также обратите внимание, что лучше использовать build, а не create, если вам не нужно на самом деле сохранить запись в базе данных, так как это дешевле, операция, и вы получите тот же результат , если по какой-то причине ваша запись не должна быть сохранена в базе данных, чтобы ваши тесты работали так, как вы хотите, например, сохранение первой записи в вашем примере.

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