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