rspec を使用して rake タスクのコンテキスト内でオブジェクトをスパイするにはどうすればよいですか?
概要
次の設定があります。
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
なぜそうなるのか:
(単純な(クラス)).test
期待: 引数を指定して 1 回
受信: 引数を指定した場合は 0 回
rake タスクのコンテキストと rspec について何か足りないものはありますか?
解決策
accept の代わりに have_received を使用するべきでした。これは、アサーションの前にすでにタスク (したがって Simple.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
これがテスト結果です。