2014-09-29 1 views
0

Прежде всего, я должен, вероятно, упомянуть, что я очень новичок в Rails, и это мой первый «серьезный» проект, поэтому я приношу свои извинения, если это простой вопрос, но Я не могу найти для этого ответа.Тест RSpec для недопущения двух пользователей с одинаковым адресом электронной почты

Я использую TDD в своем проекте и использую RSpec для написания модельных тестов FactoryGirl для создания моделей и Faker для создания фиктивных данных для моделей. Все прошло очень хорошо, пока я не добавил тест, чтобы убедиться, что у двух пользователей нет одинакового адреса электронной почты. В моей User модели я подтверждено его следующим образом:

# /app/models/user.rb 
validates :email, :password_reset_code, :auth_token, uniqueness: true 

Моя фабрика создает пользовательскую модель с Faker, например так:

# /spec/factories/users.rb 
FactoryGirl.define do 
    factory :user do 
    email { Faker::Internet.email } 
    password { Faker::Internet.password } 
    password_reset_code { Faker::Lorem.word } 
    auth_token { Faker::Lorem.word } 
    end 
end 

и мой user_spec.rb тест на это следующим образом:

# /spec/models/user_spec.rb 
it "is invalid with a duplicate email" do 
    user = FactoryGirl.create(:user) 
    FactoryGirl.create(:user, email: user.email).should_not be_valid 
end 

Здесь я создаю новую модель с FactoryGirl, используя ее фиктивные значения из Faker, сохраняя ее в базе данных, а затем создавая другую с тем же адресом, что и первый. Я бы ожидал, что RSpec скажет мне, что этот тест прошел из-за части should_not be_valid. Но вместо этого я получаю этот выход, когда я запускаю тест:

Failures: 

    1) User is invalid with a duplicate email 
    Failure/Error: FactoryGirl.create(:user, email: user.email).should_not be_valid 
    ActiveRecord::RecordInvalid: 
     Validation failed: Email has already been taken 
    # ./spec/models/user_spec.rb:19:in `block (2 levels) in <top (required)>' 

Так что, кажется, что проверка достоверности модели является повышение ошибка, которая RSpec не ловить и использовать, чтобы пройти тест? Я сумел обойти его, изменив тест на это:

it "is invalid with a duplicate email" do 
    begin 
    user = FactoryGirl.create(:user) 
    FactoryGirl.create(:user, email: user.email).should_not be_valid 
    rescue 
    false 
    end 
end 

который кажется работать, однако у меня есть чувство, что это не самый лучший способ сделать это.

Каков правильный способ написать этот тест?

+0

им не уверен, если его отношение или нет, но быстрый поиск дал мне это https://github.com/rspec/rspec-expectations/blob/master/Should .md – eno3nt

ответ

1

Я столкнулся с этой проблемой. Ошибка, с которой вы сталкиваетесь, связана с тем, что метод create() фактически сохраняет модель, которая затем бросает ActiveRecord :: RecordInvalid на уровне БД (ну, слой сохранения). Если вы хотите утверждать, что модель действительна или нет, вы должны использовать метод build() для вашего второго объекта, а затем спросить, действительно ли это. Вы можете прочитать об этом в этом post.

Кроме того, если вы просто пытаетесь проверить различные валидации на моделях и что я не написал быстрый и грязный камень, который вы можете использовать, чтобы утверждать некоторые из более основополагающих валидаций модели. Вы можете проверить это here.

Надеюсь, что это поможет.

+0

FYI, если бы вы использовали драгоценный камень, с которым я связался с вами, можно проверить уникальность с помощью следующей строки кода: 'Record.field_uniqueness (FactoryGirl.create (: user),: email)' – mattforni

+0

Спасибо, изменил второй 'create' to' build', и теперь он отлично работает. Этот драгоценный камень выглядит полезным, я посмотрю :) –

0

Я бы с:

# /spec/models/user_spec.rb 
describe 'validations' do 

    context 'with a duplicate email' do 
    let(:other_user) { FactoryGirl.create(:user) } 
    let(:attributes) { FactoryGirl.attributes_for(:user) } 

    subject(:user) { User.new(attributes.merge(email: user.email)) } 

    it 'is not valid' do 
     expect(user).to_not be_valid 
    end 
    end 
end 
Смежные вопросы