从rspec文档中,expect_any_instance_of()
已被弃用。但是,到目前为止,我还没有找到一种简单的方法来替换该方法。到目前为止,我尝试过的所有方法都失败了,尤其是调用了预期会被嘲笑的方法。
context 'test Foo' do
before(:each) do
info = double(
size: 12345,close: true
)
allow(Blah).to receive(:open).and_return(info) # this one works
end
it 'returns false on failure' do
# This expect_any_instance_of() works like a charm
expect_any_instance_of(MyUploader).to receive(:process_with_some_tool).and_return(false)
uploader = MyUploader.new(create(:my_object,data: nil))
# These expect()'s fails
expect(MyUploader).to receive(:process_with_some_tool).and_return(true)
expect(uploader).to receive(:process_with_some_tool).and_return(true)
uploader.store!(trigger_data)
end
end
第一个expect(MyUploader)
(因此使用类名),我也尝试将其放置在before
块中。我有点期待它无论如何都会失败,因为uploader
对象的类名在运行时看起来像这样(当然,每次运行时数字也会变化):
MyUploader::Uploader47181996911040
但是,我不明白为什么expect(uploader)
(也就是我刚刚分配的对象)也失败了。由于我隶属于创建的对象,因此为什么不模拟:process_with_some_tool
事件并仅返回true
?
我的puts "CALLED\n"
中有一个:process_with_some_tool
,当我使用expect()
时看到了该消息。使用expect_any_instance_of()
时看不到它。因此,前者不会嘲笑任何东西,而后者会像预期的那样嘲笑……
我还尝试将自己的脑袋缠在Method stubs帮助页面上,但同样,我仍然无法使其正常工作。
所以我的问题是:我们如何转换expect_any_instance_of()
使其真正起作用?
注意:我是Ruby,Rails,RSpec和所有这些的新手。我怀疑这很简单,但我只是不知道如何使它全部起作用...
该实现是专有的,但这是我使用的基本表示:
class MyUploader < CarrierWave::Uploader::Base
include Inspectable
version :cleanup do
process :func1
process :func2
process :func3
after :store,:check_size
end
def func1
# Do work
end
def func2
if info.close
tmpfile = 'temp_file1.ext'
successful_processing = process_with_some_tool1(tmpfile)
log "message 1" unless successful_processing
end
if !info.close
tmpfile = 'temp_file2.ext'
successful_processing = process_with_some_tool2(tmpfile)
log "message 2" unless successful_processing
end
end
def func3
# Do work
end
def process_with_some_tool1(tmpfile)
puts "TOOL1 RUN"
system %Q{mytool1 -a -b -c "#{tmpfile}"}
end
def process_with_some_tool2(tmpfile)
puts "TOOL2 RUN"
system %Q{mytool2 -a -b -c "#{tmpfile}"}
end
def check_size
begin
if size < 100
raise "Too small"
end
rescue => error
log "some message"
end
end
end
这是我所拥有的基本代表。该代码是专有的,所以我不能只复制粘贴整个内容。
当我期望一个(和tool1)由于"TOOL2 RUN"
而成为存根时,我看到的是expect()
消息。
请注意,这里没有实现store
。所以它来自基类。
更新:
我看到store!()
调用cache()
,并且调用versions!()
,并且versions!()
实现包括以下初始化函数:
def build_version(name,options)
uploader = Class.new(self)
const_set("Uploader#{uploader.object_id}".gsub('-','_'),uploader)
uploader.version_names += [name]
...snip...
end
我们可以看到,该函数创建了一个新类,并将其命名为“ Uploader ”,这正是我将class / object_id打印到控制台时所看到的。
检查所有ID,现在我可以看到测试中使用的实际对象是这个Class.new()
创建的对象,而不是我在代码中创建的对象。
此build_version
方法来自~/.rvm/gems/ruby-2.5.3/gems/carrierwave-0.11.0/lib/carrierwave/uploader/versions.rb
。它是上载器功能的一部分,该功能可缓存测试文件。看起来,它似乎不仅限于缓存文件...现在,我想知道是否可以访问该缓存的对象,并允许将我的expect()
或allow()
附加到该版本。我将特别检查Carrierwave implementers。他们更有可能解决此问题。