只模拟一次方法
问题描述:
在替换原始模拟方法之前,有没有一种方法可以在每次期望中只模拟一次方法一次?只模拟一次方法
我觉得像这样的工作(注意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
不幸的是我得到这个错误:
(Klass (class)).meth(no args)
expected: 1 time with any arguments
received: 2 times
我本来预期已经得到了失败,如果我说expect(Klass).to receive(:meth).once
而比较宽松的allow
。
我想知道我怎样才能嘲笑一次和每期望一次。
答
这可能有点不直观,但你可以通过specifying different return values for multiple calls的Klass.meth
来做到这一点。
在你的情况,你可以用'foo'
存根Klass.meth
第一个呼叫,然后存根每隔调用Klass.meth
与原来实行的方法。这看起来是这样的:
allow(described_class).to receive(:meth).and_return('foo', described_class.meth)
我们需要在您的测试是在最后的测试不使用subject
改变,因为它是memoising返回值时Klass.meth
被称为第一次接下来的事情(这就是为什么所有使用subject
的其他测试仍会通过),因此测试中的第二个期望失败。相反,我们可以直接在每个规范中调用该方法:
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