如何解决Rswag测试中FactoryBot创建的Account失效问题?
解决Rswag测试中FactoryBot创建的记录无法被ActiveRecord识别的问题
你遇到的核心问题是FactoryBot创建的记录不在Rswag测试的数据库事务上下文里,导致模型校验时查不到目标记录。以下是两种可行的解决方案:
方案1:用嵌套let创建记录
把Account的创建逻辑放到let块中,确保记录在测试运行的事务内生成:
parameter name: :account_id, in: :query, type: :integer response(422, 'account not permitted') do let(:account) { FactoryBot.create(:account, forbidden: true) } let(:account_id) { account.id } run_test! end
let是延迟加载的,会在run_test!执行时才创建Account,此时已经处于测试的数据库事务中,模型校验时就能正常查询到这条记录。
方案2:用before块结合实例变量
如果需要提前初始化记录,可以用before块创建实例变量,再通过let引用:
parameter name: :account_id, in: :query, type: :integer response(422, 'account not permitted') do before do @account = FactoryBot.create(:account, forbidden: true) end let(:account_id) { @account.id } run_test! end
before块会在测试运行前执行,创建的@account处于测试事务内,后续let(:account_id)引用它的ID就能被模型正确识别。
你的两种尝试失败原因
- 第一种方案:在response块顶层直接执行
account = FactoryBot.create(...)时,Rswag的测试事务还未启动,这条记录是在事务外创建的。而模型校验是在测试事务内执行的,受事务隔离机制限制,无法查询到事务外的记录,导致校验失败。 - 第二种方案:
let是RSpec的DSL,只能在示例组的顶层定义,不能在before块内部调用。let的作用是定义延迟加载的变量,并非动态赋值的方法,因此这种写法本身就不符合语法规则。
内容的提问来源于stack exchange,提问作者Stacker
相关产品推荐
相关产品推荐

