[英]Issue stubbing with RSpec
I am trying to understand why the result of these tests, the first test claims the method is not stubbed, however, the 2nd one is. 我试图理解为什么这些测试的结果,第一个测试声称该方法不是存根,但是,第二个是。
class Roll
def initialize
install if !installed?
end
def install; puts 'install'; end
end
describe Roll do
before do
class RollTestClass < Roll; end
RollTestClass.any_instance.stub(:install)
end
let(:roll_class) { RollTestClass }
let(:roll) { RollTestClass.new }
context 'when installed is true' do
before do
roll_class.any_instance.stub(:installed?).and_return(true)
end
it 'should not call install' do
expect(roll).to_not have_received(:install)
end
end
context 'when installed is false' do
before do
roll_class.any_instance.stub(:installed?).and_return(false)
end
it 'should call install' do
expect(roll).to have_received(:install)
end
end
end
It's also strange the error says expected to have received install
, but I think that is likely just faulty feedback from the RSpec DSL. 同样奇怪的是错误说
expected to have received install
,但我认为这可能只是来自RSpec DSL的错误反馈。 But maybe worth noting. 但也许值得注意。
1) Roll when installed is true should not call install
Failure/Error: expect(roll).to_not have_received(:install)
#<RollTestClass:0x10f69ef78> expected to have received install, but that method has not been stubbed.
The "spy pattern" of RSpec requires that the objects have been previously stubbed. RSpec的“间谍模式”要求对象先前已被存根。 However,
any_instance.stub
doesn't actually stub the methods "for real" unless/until the method is invoked on a particular object. 但是,
any_instance.stub
实际上不会将方法“for real”存根,除非/直到在特定对象上调用该方法。 As such, the methods appears as being "unstubbed" and you get the error you're getting. 因此,这些方法显示为“未被取消”,您将收到错误。 Here's some code that demonstrates the change in definition:
以下是一些演示定义更改的代码:
class Foo
end
describe "" do
it "" do
Foo.any_instance.stub(:bar)
foo1 = Foo.new
foo2 = Foo.new
print_bars = -> (context) {puts "#{context}, foo1#bar is #{foo1.method(:bar)}, foo2#bar is #{foo2.method(:bar)}"}
print_bars['before call']
foo1.bar
print_bars['after call']
end
end
which produces the following output: 产生以下输出:
before call, foo1#bar is #<Method: Foo#bar>, foo2#bar is #<Method: Foo#bar>
after call, foo1#bar is #<Method: #<Foo:0x007fc0c3842ef8>.bar>, foo2#bar is #<Method: Foo#bar>
I reported this an issue on RSpec's github site and got this acknowledgement/response . 我在RSpec的github网站上报告了这个问题,得到了这个确认/回复 。
You can use the following alternative approach, which depends on the recently introduced expect_any_instance_of
method. 您可以使用以下替代方法,该方法取决于最近引入的
expect_any_instance_of
方法。
class Roll
def initialize
install if !installed?
end
def install; puts 'install'; end
end
describe Roll do
before do
class RollTestClass < Roll; end
end
let(:roll_class) { RollTestClass }
let(:roll) { RollTestClass.new }
context 'when installed is true' do
before do
roll_class.any_instance.stub(:installed?).and_return(true)
end
it 'should not call install' do
expect_any_instance_of(roll_class).to_not receive(:install)
roll
end
end
context 'when installed is false' do
before do
roll_class.any_instance.stub(:installed?).and_return(false)
end
it 'should call install' do
expect_any_instance_of(roll_class).to receive(:install)
roll
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.