【问题标题】:Why is ActiveRecord creating different ruby object when querying the same record?为什么 ActiveRecord 在查询同一记录时会创建不同的 ruby​​ 对象?
【发布时间】:2018-05-18 21:56:39
【问题描述】:

我正在尝试使用 FactoryBot 使用 RSpec 在我的 Rails 模型中测试命名范围。我正在创建几条记录,其中范围只返回一条。

RSpec.describe GemNamespace::GemModel, type: :model do

  before(:all)
    FactoryBot.create(:gem_model, :trait1)  # id 1
    FactoryBot.create(:gem_model, :trait2)  # id 2
    FactoryBot.create(:gem_model, :trait3)  # id 3
  end

  let(:included_record) { GemNamespace::GemModel.find 1 }

  describe 'my_named_scope' do
    it 'returns only records matching the conditions' do
      scope_results = GemNamespace::GemModel.my_named_scope
      expect(scope_results).to contain_exactly(included_record)
    end
  end

end

测试失败是因为尽管included_recordscope_results 中的唯一记录,但由于某种原因,一些调试显示included_record 实际上是与结果中的对象不同的Ruby 对象。因此,contain_exactly 失败。

我已经在大量模型上进行了这样的范围测试,并且始终有效。与这个唯一的区别是模型是在 gem 中定义的,我通过在我的 Rails 应用程序中添加我的命名范围来扩展它的功能。

我错过了什么?为什么它只对这个模型有这样的行为?

如果重要的话:

  • Ruby 2.5.0
  • Rails 5.1.5
  • rspec 3.7.0
  • rspec-rails 3.7.2
  • factory_bot(_rails) 4.8.2

更新:我会把它放在这里而不是编辑上面的。我实际上正在测试数据库视图而不是表。视图没有唯一的 id 列,所以我实际上并没有在上面做一个GemNamespace::GemModel.find 1,而是一个where(column: <condition value>)

【问题讨论】:

    标签: unit-testing activerecord rspec


    【解决方案1】:

    我通过解决方法解决了这个问题。我不太了解 Rails 的内部结构,但似乎没有 id 列的数据库视图(和相应的模型)有点搞砸了(即创建了单独的 Ruby 对象)。所以我只是“手动”比较了两个对象的所有值

    # As a workaround, we're just gonna convert them both to Ruby hashes using
    # the #as_json method, and compare those instead.
    
    expect(scope_results.as_json).to contain_exactly(included_record.as_json)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多