当我在规范中定义一个变量然后调用关联方法时,它们似乎并不一致地查询数据库。有些似乎卡住了。如果能提供任何帮助,我将非常感激,因为我之前遇到过这个问题,并且只能通过使用
find
显式查询数据库来解决它。这似乎在不同程度上持续存在于let
、let!
和before
块中。然而,它确实适用于方法定义或通过调用find
。我的问题是我如何在这里使用 let!
语法或 rspec 提供的任何东西,而不是我的 no so pretty hack.
例如,这对
let
没有按预期工作,但与 let!
一起工作(计数意外变化):
require 'rails_helper'
RSpec.describe Form::Adaption, type: :model do
context 'when a revision gets created' do
let(:app) { create(:form_application, revision_counter: 1) } # NOTE: this creates an adaption
let(:rev_adap) { create(:form_adaption, action_type: 'revision', application: app) }
it '...' do
doc_adap = create(:form_adaption, action_type: 'document', application: app)
expect(doc_adap.application.revision?).to be true
# NOTE: DB Cleaner gem destroys doc_adaption
end
describe '...' do
it '...' do
# ISSUE:
puts "app.adaptions.count: #{app.adaptions.count}" # => 1
puts "rev_adap.application.adaptions.count: #{rev_adap.application.adaptions.count}" # => 2
puts "App.find(adap.id).adaptions #{Form::Application.find(rev_adap.application_id).adaptions.count}" # => 2
create(:form_adaption, action_type: 'document', application: app)
# Utter Confusion:
puts "app.adaptions.count: #{app.adaptions.count}" # => 3
puts "rev_adap.application.adaptions.count: #{rev_adap.application.adaptions.count}" # => 3
puts "App.find(adap.id).adaptions #{Form::Application.find(rev_adap.application_id).adaptions.count}" # => 3
# ...
end
end
end
end
当切换到 not 懒惰评估
let!
它确实与调试 puts
调用一起工作。
let!(:app) { create(:form_application, revision_counter: 1) }
let!(:rev_adap) { create(:form_adaption, action_type: 'revision', application: app) }
=> 2, 2, 2, 3, 3, 3
在上面的puts
中。
但是我想运行的实际测试仍然失败,因为
app.adaptions
返回一个空数组,即使在 puts
上面的一行中打印计数为 4.
# i use let! to define the app and rev_adap but this also happens with regular let
it 'the relevant it block from above' do
# ...
post_revision_doc_adap = create(:form_adaption, action_type: 'document', application: app)
puts "Adap count: #{app.adaptions.count}" # => 4 as expected
pp app.adaptions.first # => nil
app.adaptions.sample(1).revision_manager
# ISSUE: => undefined method `revision_manager' for []:Array
所以
app
似乎“卡住了”,但这会根据上下文发生变化。由于延迟加载,它不会在使用 let
定义时查询数据库以了解其相关适配的更改,但是问题甚至在其他地方的 let!
仍然存在。
当我
app
和 rev_adap
作为 before
块中的实例变量时,我得到相同的最终错误。
但是,当我将 app
和 rev_adap
定义为这样的方法时:
def app
@__a ||= create(:form_application, revision_counter: 1)
Form::Application.find(@__a.id)
end
def rev_adap
@__a2 ||= create(:form_adaption, action_type: 'revision', application: app)
Form::Adaption.find(@__a2.id)
end
并运行有问题的
it
块它确实有点工作:
# ...
doc_adap = create(:form_adaption, action_type: 'document', application: app)
# ...
pp app.adaptions # => collection witth four adaptions as expected
pp app.adaptions.sample() # => collection with one adaption ( number of adaptions after factory bot done )
但是我仍然得到与
let
顶部相同的奇怪计数行为。
我知道这不是与 rails 相关的问题,因为在 rails 控制台中定义
app
并为其创建新的 Form::Adaptions
然后将它们反映在 app.adaptions.count
中是没有问题的。我在常规应用程序的创建过程中也没有找到任何东西,而不是在查找应用程序的 FactoryBot 中。只有 save!
被调用。我没有在这里查看 Rails 内部结构。
我试着在 ActiveRecord Association Source 中四处寻找,因为我没有真正找到任何关于“rspec test rails associations”的明确内容。
我无法将这个问题或这个与我的问题联系起来。第一个看起来很相似但不是很详细,第二个似乎没有关系,因为我肯定通过
create
策略坚持所有的FactoryBot用法。
除了 rspec 和 rspec_rails 之外,我还使用 factory_bot 和 db_cleaner gem。
Ruby 版本为 2.7.2,rails 为 6.0.6.1
Rspec 版本是: RSpec 3.12