2012-03-16 5 views
2

私のrspecの例をループで実行する際に問題があります。rspec letメソッド+ループ

describe "GET all providers" do 
    let(:current_user) { Factory(:user) } 

    [:twitter, :facebook, :google_oauth2].each do |provider| 
     before :each do 
     current_user.confirm! 
     sign_in current_user 

     request.env['devise.mapping'] = Devise.mappings[:user] 
     request.env["omniauth.auth"] = OmniAuth.config.add_mock provider, { 
      :uid => '123456789', 
      :info => { 
      :email => current_user.email 
      } 
     } 
     end 

     it 'should add the authorization' do    
     get provider # method to create the authorization 
     authorization = Authorization.where(:provider => request.env["omniauth.auth"][:provider], :uid => request.env["omniauth.auth"][:uid]).first 
     current_user.authorizations.should include authorization 
     end 
    end 
    end 

現在、これらの例はすべて合格です。しかし、問題は、current_userメソッドをメモしているにもかかわらず、current_userがループの各反復を通じて新しいユーザーインスタンスであることです。もし私がcurrent_user.authorizations.count.should == 3のテストを追加すると失敗します。

これは実際にそれをテストする必要性が少なくなり、なぜ私がどのように動作するのかわかりません。 let(:current_user) { Factory(:user) }は、すべての例で同じユーザーインスタンスを保持するべきではありませんか?ここで

答えて

1

は、私はそれを思い付いたの要旨はあなたがletlet!を理解するのに役立つかもしれないです: https://gist.github.com/3489451

letは、それが最初に呼び出されるたびに、各it例の中に戻り値をmemoizesが、ブロックを実行しますこの例では、

たとえば、itサンプルブロックでcurrent_userを初めて呼び出すと、{ Factory(:user) }ブロックが実行されます。同一のitサンプルブロック内でcurrent_userを2番目以降の時刻に呼び出すと、{ Factory(:user) }ブロックは実行されません。戻り値がメモされます。

+0

ありがとうございます。この文の前に私には分かりませんでした: 'let'は各' it'の例の中で戻り値をメモしますが、例では最初に呼び出されるたびにブロックを実行します。 – Francois