2014-09-26 311 views
0

我對FactoryGirl和RSpec有問題。我有以下測試:使用Rspec let進行測試失敗

require 'rails_helper' 
describe Customer do 
    it_behaves_like "Account" 

    describe "it has an address" do 
    let(:customer) {create(:customer)} 
    let(:address) {create(:address, addressable_id: customer.id, addressable_type: "Account")} 

    it "should have an address" do 
     expect(customer.address).to eq address 
    end 
    end 
end 

當我嘗試運行它拋出我下面的錯誤:

) Customer it has an address should have an address 
    Failure/Error: expect(customer.address).to eq address 

     expected: #<Address id: 1, street: "Street 1", zip_code: "11-111", city: "City 1", addressable_id: 1, addressable_type: "Account", created_at: "2014-09-26 10:07:51", updated_at: "2014-09-26 10:07:51"> 
      got: nil 

     (compared using ==) 
    # ./spec/models/customer_spec.rb:11:in `block (3 levels) in <top (required)>' 

但是當我把它重構爲這樣的事情:

require 'rails_helper' 

describe Customer do 
    it_behaves_like "Account" 

    describe "it has an address" do 
    before do 
     @customer = create(:customer) 
     @address = create(:address, addressable_id: @customer.id, addressable_type: "Account") 
    end 

    it "should have an address" do 
     expect(@customer.address).to eq @address 
    end 
    end 
end 

它可以正常工作。爲什麼我的例子與失敗?

+0

向您的工廠展示 – BroiSatse 2014-09-26 10:23:32

回答

3

這是因爲let被懶惰地評價。

調用expect(customer.address)會調用您的第一個let塊,即create(:customer)。它返回一個沒有地址的customer

第二個letcreate(:address, ...)直到調用eq address才被調用。

您可以使用let!即時創建地址:

let!(:address) { create(:address, ...) } 

另一種選擇是使用自定義的工廠customer_with_address那臺association