FactoryGirl, Rspec, let, и до проблем
Я использую некоторые из этих инструментов в первый раз. Я прочитал документы, но хотел спросить здесь, что именно я пытаюсь достичь.
У меня есть набор пользователей, которым я хочу проверить некоторые действия, которые я могу выполнить в спецификации контроллера. Когда каждый пользователь создан, существует набор обратных вызовов, которые возникают для создания связанных объектов.
Я хотел бы иметь доступ к этим пользовательским экземплярам и связанным объектам этого класса ActiveRecord. Например, у пользователя будет набор списков, поэтому я бы хотел, например, вызвать user1.lists.
Кроме того, я хотел бы изолировать эту установку вверху и использовать либо let, либо a before black. Кажется, что просто позвонить можно так:
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let(:user) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user2) }
не вызывает связанные обратные вызовы. Это верно? Или это может быть вопрос времени?
Мне нравится синтаксис использования let и возможность доступа к этим объектам в моих примерах, таких как user.id, но не могу получить доступ к user.lists. В настоящее время я делаю что-то вроде:
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let(:user) { FactoryGirl.create(:user) }
let(:user2) { FactoryGirl.create(:user2) }
let(:user3) { FactoryGirl.create(:user3) }
before do
FactoryGirl.create(:user2)
FactoryGirl.create(:user3)
end
но чувствую, что должен быть лучший способ. Я создаю этих пользователей дважды?
ТНХ
изменить 1
Я выделил здесь код. Значение global_id создается с помощью обратного вызова. Он существует правильно в db и может быть доступен через соответствующую find_by_email, но использование user2 var не обеспечивает доступ.
require 'spec_helper'
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let!(:user) { FactoryGirl.create(:user) }
let!(:user2) { FactoryGirl.create(:user2) }
let!(:user3) { FactoryGirl.create(:user3) }
before do
session[:user_id]=user.id # works
end
describe 'FOLLOW / UNFOLLOW options' do
it 'shall test the ability to follow another user' do
puts "user1: " + user.global_id.to_s # doesn't output anything
u2=User.find_by_email('[email protected]') # corresponds to user2
post :follow, :global_id => user2.global_id # doesn't work
#post :follow, :global_id => u2.global_id #works
u3=User.find_by_email('[email protected]')
puts "user_3" + u3.global_id.to_s # outputs correct value
post :follow, :global_id => user3.global_id #doesn't work
#post :follow, :global_id => u3.global_id # works
post :unfollow, :global_id => user.following.sample(1)
response.code.should eq('200')
end
end
end
Ответы
Ответ 1
Проверьте rspec doc: https://www.relishapp.com/rspec/rspec-core/v/2-11/docs/helper-methods/let-and-let
Обратите внимание, что пусть lazy-оценивается: он не оценивается до тех пор, пока не будет вызван метод, который он определяет. Вы можете использовать let! для принудительного вызова метода перед каждым примером.
Другими словами, если вы используете let
вместе с factory_girl
, запись не будет создана перед вызовом переменной-переменной.
Правильный код:
# will test that get_count_for_list will return 5
describe ApiController do
# why same name - seems really confusing!
let!(:user) { FactoryGirl.create(:user) }
let!(:user2) { FactoryGirl.create(:user2) }
Ответ 2
Я просто решил аналогичную проблему звучания. Моя спецификация аутентификации пользователей не передавалась с использованием "let".
моя сломанная спецификация:
describe "signin" do
before { visit signin_path }
describe "with valid information", :js => true do
let(:user) { FactoryGirl.create(:user) }
before do
fill_in "email", with: user.email
fill_in "password", with: user.password
click_button "Log In"
end
it { should have_selector('a', text: "#{user.first} #{user.last}") }
end
end
Это не сработало. Аутентификация входа в систему была неудачной, как если бы пользовательская запись не была фактически в базе данных, когда мой контроллер сеанса пытается ее аутентифицировать. Я попытался заменить let let let! но это ничего не исправить. Чтение этого сообщения и ссылка выше, объясняя, пусть и пусть! Я понял, что я не должен использовать let для этой спецификации. Теперь у меня есть пропуская спецификация:
describe "signin" do
before { visit signin_path }
describe "with valid information", :js => true do
user = FactoryGirl.create(:user)
before do
fill_in "email", with: user.email
fill_in "password", with: user.password
click_button "Log In"
end
it { should have_selector('a', text: "#{user.first} #{user.last}") }
end
end