在替换原始的模拟方法之前,有没有办法模拟一个方法一次且每个期望只模拟一次?
我认为这样的事情会起作用(注意once)
class Klass
def self.meth
'baz'
end
end
describe Klass do
subject{ described_class.meth }
before{ allow(described_class).to receive(:meth).once.and_return('foo') }
it{ is_expected.to eq 'foo' }
context 'throwing in a context just to test' do
it{ is_expected.to eq 'foo' }
it{ is_expected.to eq 'foo' }
it{ is_expected.to eq 'foo' }
it 'only mocks once' do
expect(subject).to eq 'foo'
expect(subject).to eq 'baz' # this is the key
end # pass
end
end
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到此错误:
(Klass (class)).meth(no args)
expected: 1 time with any arguments
received: 2 times
Run Code Online (Sandbox Code Playgroud)
如果我说expect(Klass).to receive(:meth).once而不是更宽容的话,我本来希望会失败allow。
我想知道如何才能模拟一次并且每个期望只模拟一次。
这或许有点不直观,但是你可以通过做多的呼叫指定不同的返回值的Klass.meth。
在您的情况下,您可以存根对Klass.methwith的第一次调用'foo',然后存根对Klass.methwith的原始调用的所有其他调用。看起来像这样:
allow(described_class).to receive(:meth).and_return('foo', described_class.meth)
我们需要在您的测试中更改的下一件事是不要subject在最终测试中使用,因为它会记住Klass.meth第一次调用时返回的值(这就是为什么所有其他使用的测试subject仍然会通过),并且因此使it 'only mocks once'测试中的第二个期望失败。相反,我们可以直接在每个规范中调用该方法:
class Klass
def self.meth
'baz'
end
end
describe Klass do
subject { described_class.meth }
before do
allow(described_class).to \
receive(:meth).and_return('foo', described_class.meth)
end
it { is_expected.to eq 'foo' }
context 'throwing in a context just to test' do
it { is_expected.to eq 'foo' }
it { is_expected.to eq 'foo' }
it { is_expected.to eq 'foo' }
it 'only mocks once' do
expect(described_class.meth).to eq 'foo'
expect(described_class.meth).to eq 'baz'
end # pass
end
end
Run Code Online (Sandbox Code Playgroud)