【问题标题】:Test with Rspec let is failing使用 Rspec let 测试失败
【发布时间】:2014-09-26 10:10:43
【问题描述】:

我对 FactoryGirl 和 RSpec 有疑问。我有以下测试:

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

它工作正常。为什么我的 let 示例失败了?

【问题讨论】:

    标签: ruby-on-rails ruby rspec factory-bot


    【解决方案1】:

    那是因为 let 被延迟评估。

    调用 expect(customer.address) 会调用您的第一个 let 块,即 create(:customer) 。它返回一个没有地址的customer

    在调用eq address 之前,不会调用第二个letcreate(:address, ...)

    您可以使用let! 立即创建地址:

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

    另一种选择是使用自定义工厂customer_with_address 来设置association

    【讨论】:

      猜你喜欢
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多