我在插入外部api时遇到问题,以下是示例
require 'rspec'
require 'google/apis/storage_v1'
module Google
class Storage
def upload file
puts '#' * 90
puts "File #{file} is uploaded to google cloud"
end
end
end
class UploadWorker
include Sidekiq::Worker
def perform
Google::Storage.new.upload 'test.txt'
end
end
RSpec.describe UploadWorker do
it 'uploads to google cloud' do
google_cloud_instance = double(Google::Storage, insert_object: nil)
expect(google_cloud_instance).to receive(:upload)
worker = UploadWorker.new
worker.perform
end
end
Run Code Online (Sandbox Code Playgroud)
我正在尝试存根Google :: Storage类。此类在被测试的对象内实例化。如何验证此实例上的消息期望?
当我在上面的示例中运行时,我得到以下输出,这似乎合乎逻辑,我的double未被测试对象使用
(Double Google::Storage).upload(*(any args))
expected: 1 time with any arguments
received: 0 times with any arguments
Run Code Online (Sandbox Code Playgroud)
我是Rspec的新手,在此方面遇到困难,我们将不胜感激。
谢谢!
争取DI始终是一个好主意(/sf/answers/3598096351/),但是有时由于某些原因您不能这么做,因此这是在不更改“生产”代码的情况下进行存根的另一种方法。
expect_any_instance_ofit 'uploads to google cloud' do
expect_any_instance_of(Google::Storage).to receive(:insert_object)
worker = UploadWorker.new
worker.perform
end
Run Code Online (Sandbox Code Playgroud)
如果您只想测试该方法是否在任何此类对象上调用了该方法。
如果您想控制或设置更多期望,可以执行此操作
it 'uploads to google cloud' do
the_double = instance_double(Google::Storage)
expect(Google::Storage).to receive(:new).and_return(the_double)
# + optional `.with` in case you wanna assert stuff passed to the constructor
expect(the_double).to receive(:insert_object)
worker = UploadWorker.new
worker.perform
end
Run Code Online (Sandbox Code Playgroud)
再次-依赖注入更加清晰,您应该为此而努力。这是另一种可能性。