16

我是第一次使用其中一些工具。我已经阅读了文档,但想在这里确切地问一下我想要实现的目标。

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

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

另外,我想在顶部隔离此设置并使用 let's 或 a before black。似乎只是像这样调用 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) }

不调用关联的回调。它是否正确?还是可能是时间问题?

我喜欢使用 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

但觉得必须有更好的方法。我是否两次创建这些用户?

谢谢

编辑 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
4

2 回答 2

29

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

注意 let 是惰性求值的:直到它定义的方法第一次被调用时才会求值。你可以使用让!在每个示例之前强制调用方法。

换句话说,如果您使用letfactory_girl记录将不会在 let-variable 调用之前创建。

正确的代码是:

# 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) }
于 2012-08-30T18:17:52.373 回答
3

我刚刚解决了一个类似的听起来问题。我的用户身份验证规范没有使用“让”通过。

我破碎的规格:

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 的链接!我意识到我不应该在这个规范中使用 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
于 2013-04-29T21:35:15.887 回答