如何使用 rspec 在 rake 任务的上下文中监视对象?

How do I spy on objects within the context of a rake task with rspec?

提问人:ohhh 提问时间:11/14/2023 最后编辑:ohhh 更新时间:11/18/2023 访问量:46

问:

我有以下设置:

class Simple
  def self.test; end
end

task a_simple_job: :environment do
  counter = 0
  while counter < 2    
    Simple.test
    counter += 1
  end
end

require "rails_helper"
describe "a_simple_job" do
  subject { Rake::Task[:a_simple_job].invoke }
  before do
    Rails.application.load_tasks
    allow(Simple).to receive(:test)
    subject
  end

  # It seems like rspec cannot spy on objects created in the context of rake tasks
  it "calls test twice" do
    expect(Simple).to receive(:test).once
  end
end

为什么我会得到:

(Simple (class)).test

预期:1 次,带任何参数

收到: 0 次,带任何参数

我在这里缺少一些关于 rake 任务上下文和 rspec 的东西吗?

Ruby-on-Rails Ruby rSpec 耙子

评论

0赞 Stefan 11/14/2023
“预期:1 次”似乎不匹配——这是该测试的实际输出吗?receive(:test).twice
1赞 engineersmnky 11/14/2023
您可以将调用移到测试内部吗?还同意预期的 1 次与预期的 2 次不匹配,但现在您的期望是在事件发生之后,所以我相信您必须使用而不是实现间谍模式subjecthave_receivedreceive
0赞 ohhh 11/17/2023
谢谢你的建议,这是一个错别字。在尝试重新安排模拟/耙子任务加载后,我仍然无法让它工作,所以我只是在任务完成后测试了我正在寻找的 redis 值twice

答:

0赞 tonystrawberry 11/18/2023 #1

您应该使用而不是 .那是因为在断言之前,您已经调用了您的任务(因此也调用了)。have_receivedreceiveSimple.test

参考: https://rubydoc.info/github/rspec/rspec-mocks/RSpec%2FMocks%2FExampleMethods:have_received

我让它在我的机器上工作。

# lib/tasks/simple_task.rake

task a_simple_job: :environment do
  counter = 0
  while counter < 2
    Simple.test
    puts "counter: #{counter}"
    counter += 1
  end
end
# lib/simple.rb

class Simple
  def self.test
    puts "test"
  end
end
# spec/lib/tasks/simple_task_spec.rb

require "rails_helper"
require "simple"

describe "a_simple_job" do
  subject { Rake::Task[:a_simple_job].invoke }
  before do
    Rails.application.load_tasks
    allow(Simple).to receive(:test)
  end

  it "calls test twice" do
    Rake::Task[:a_simple_job].invoke
    expect(Simple).to have_received(:test).twice # Because it is called twice in the loop
  end
end

这是测试结果。

test result