有时,我们在ruby main
对象上调用方法。例如,我们为FactoryBot调用create
,为I18n调用_()
。
测试这些在RSpec中调用的顶级方法的正确方法是什么?
例如,我要测试N_
是否被调用,但是由于Rspec中的self和文件中的self不同,因此无法正常工作。
# spec
describe 'unfound_translations' do
it 'includes dynamic translations' do
expect(self).to receive(:N_)
load '/path/to/unfound_translations.rb')
end
end
# unfound_translations.rb
N_('foo')
但是这没有通过。
答案 0 :(得分:1)
好的,我现在解决你的问题。您的主要问题是self
块中的it
与self
内部的unfound_translations.rb
不同。因此,您要在一个对象上设置期望值,而在完全不同的对象上调用方法N_
。
(编辑:我刚刚意识到,当再次阅读该问题的主题时,您已经意识到了。很抱歉声明明显的问题……将其保留下来,对其他人可能有用)
我设法拥有一种有效的hacky方式,这里是:
# missing_translations.rb
N_('foo')
和规范(为简单起见,我在其中定义了一个用于测试的简单模块):
module N
def N_(what)
puts what
end
end
RSpec.describe 'foo' do
let(:klass) do
Class.new do
extend N
end
end
it do
expect(klass).to receive(:N_)
klass.class_eval do
eval(File.read('missing_translations.rb'))
end
end
end
它的作用是创建一个匿名类。评估内部missing_translations.rb
的内容意味着klass
是接收thing
方法的N_
。因此,您可以在那里设定期望。
我很确定您可以将extend N
模块替换为任何给您提供N_
方法的模块,这应该可以工作。
这很hacky,但工作量不大,因此在提供更优雅的解决方案之前可能就足够了。