因此,我在测试ruby类时遇到了这种奇怪的行为。我顺便使用rspec 3来测试它。
Class Foo有一个方法&f; fetch_object'它叫做'找到'从类Bar中检索对象的方法,而不是调用方法' fail'来自获取的对象。
所谓奇怪的行为发生在我希望收到方法“失败”的时候。一旦收到,但如果我更改了' faill'它就像一个魅力:S
这是戏剧:
require 'ostruct'
class Foo
def fetch_object
foobar = Bar.find
foobar.fail
end
end
class Bar
def self.find
OpenStruct.new(name: 'Foo Bar')
end
end
describe Foo do
subject { Foo.new }
let(:foo) { OpenStruct.new() }
before do
expect(Bar).to receive(:find).and_return(foo)
end
it 'fetch object with name' do
expect(foo).to receive(:fail)
subject.fetch_object
end
end
答案 0 :(得分:1)
我怀疑它是因为你正在设置对象的期望,这种行为取决于method_missing
(OpenStruct
)。
因为这个原因我不想把它作为模拟,我会使用常规模拟(并且规范会通过):
let(:foo) { double('foobar') }
您正在此处进行测试,如果返回的对象(Bar.find的结果)将收到预期的消息,而不会进入实现细节。
设置像ostruct这样的动态类的期望可能会导致奇怪的结果。似乎在某些时候调用Kernel#fail
方法,因此,将名称更改为faill
或任何其他尚未采用的方法"通过内核将使它工作。
其他解决方案是monkeypatching OpenStruct以避免调用method_missing
:
class OpenStruct
def fail
true
end
end
class Foo
def fetch_object
foobar = Bar.find
foobar.fail
end
end
class Bar
def self.find
OpenStruct.new(name: 'Foo Bar')
end
end
describe Foo do
subject { Foo.new }
let(:foo) { OpenStruct.new }
before do
expect(Bar).to receive(:find).and_return(foo)
end
it 'fetch object with name' do
expect(foo).to receive(:fail)
subject.fetch_object
end
end
但我不知道你为什么要那样做;)