FactoryGirl,Rspec,let和之前的问题

tim*_*one 15 rspec ruby-on-rails

我是第一次使用这些工具.我已经阅读了文档但是想在这里问我到底想要实现的目标.

我有一组用户,我想测试一些我可以在控制器规范中执行的操作.创建每个用户时,会发生一组回调以创建关联对象.

我想访问这些用户实例以及该ActiveRecord类的关联对象.例如,用户将拥有一组列表,因此我希望能够调用user1.lists.

另外,我想在顶部隔离这个设置并使用let或者之前的黑色.似乎只是这样调用let:

# 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) }
Run Code Online (Sandbox Code Playgroud)

不会调用关联的回调.它是否正确?或者它可能是一个时间问题?

我喜欢使用let的语法,并且能够在我的ExampleGroups中访问这些对象,例如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
Run Code Online (Sandbox Code Playgroud)

但是觉得必须有更好的方法.我是否创建了这两个用户?

谢谢

编辑1

我在这里分离了有问题的代码.global_id值是通过回调创建的.它在数据库中正确存在,可以通过相应的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('jo@jo.com') # 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('su@su.com')
      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
Run Code Online (Sandbox Code Playgroud)

lua*_*sus 29

检查rspec doc:https://www.relishapp.com/rspec/rspec-core/v/2-11/docs/helper-methods/let-and-let

请注意,let是惰性求值的:直到第一次调用它定义的方法时才会对它进行求值.你可以用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) }
Run Code Online (Sandbox Code Playgroud)