使用 Rails.cache 时 Rspec 测试失败,但如果我执行 binding.pry 则通过

Posted

技术标签:

【中文标题】使用 Rails.cache 时 Rspec 测试失败,但如果我执行 binding.pry 则通过【英文标题】:Rspec tests failing when using Rails.cache, but pass if I do a binding.pry 【发布时间】:2020-07-15 22:07:23 【问题描述】:

我遇到了一个奇怪的问题,我正在测试一个控制器,该控制器有一个使用缓存的过程。测试失败,但如果我在执行缓存的方法中执行binding.pry,则测试通过。

包含缓存和 binding.pry 的方法示例:

def method_example:
  data = Rails.cache.fetch(cache_key) do
    ProcedureService.new(params).generate
  end

  binding.pry

  data
end

测试示例:

  it "reverts record amount" do
    expect(record.amount).to eq((original_amount + other_amount).to_d)
  end

缓存是通过 redis_store 完成的。

在开发环境中完成后,它可以正常工作。我不明白为什么它在添加塞子时失败但通过了?似乎这可能与获取缓存所需的时间有关

更新

使用 sleep 代替 binding.pry 也会使测试通过,所以我可以假设这是一个时间问题。究竟是什么问题?我该如何管理它?

【问题讨论】:

【参考方案1】:

我认为这与您的测试中启用或未启用兑现有关:

您可以在示例方法中使用当前实现设置这样的期望:

expect(Rails).to receive_massage_change(:cashe, :fetch).and_return(expected_value)

您还可以将ProcedureService 实例注入方法并对其设置期望,如下所示:

procedure_service_instance = instance_double('ProcedureService', generate: some_value_you_want_to_be_returned)

expect(procedure_service_instance).to receive(:generate)

如果您像这样制作示例方法:

def method_example
  data = Constant.fetch_from_cashe(cache_key)
  procedure_service.generate
  data
end

那么你可以摆脱receive_message_chain的期望并使用:

expect(Constant).to receive(:fetch_from_cashe).with(cashe_key).and_return(expected_value)
expect_any_instance_of(ProcedureService).to receive(:generate) some_fake_return_value 

您也可以在测试中启用缓存,请查看以下链接:link1、link2、link3

我不确切知道您的原件是在哪里以及如何编写的,但是根据您提供的示例方法,我认为对发送的方法设置期望值就可以了。请注意,您的目标不是测试 Rails 兑现,而是测试您的代码是否按照您的意愿使用它。

【讨论】:

以上是关于使用 Rails.cache 时 Rspec 测试失败,但如果我执行 binding.pry 则通过的主要内容,如果未能解决你的问题,请参考以下文章

使用 RSpec 测试 Rails 辅助方法时如何在参数哈希中设置值?

Rails:在 RSpec 测试查看编辑表单时出错

如何在 rspec 中运行单个测试?

使用应该匹配器使用 RSPEC 测试我的控制器时发生错误,特别是创建我无法测试保存功能

使用 rspec 测试视图 - 渲染视图时帮助文件中未定义的 current_user

在 rspec 测试用例中启动弹性搜索集群时权限被拒绝