1
在rspec的3.1.0中的语法,一个规范可以使用#allow存根的方法:能够想到一类
describe do
specify do
o = Object.new
allow(o).to receive(:foo)
o.foo
end
end
这工作得很好。但是,如果短线在一个类中的方法内,则#allow方法没有定义:
describe do
class Baz
def allow_bar(o)
allow(o).to receive(:bar)
end
end
specify do
o = Object.new
Baz.new.allow_bar(o)
o.bar
end
end
的错误是:
Failure/Error: allow(o).to receive(:bar)
NoMethodError:
undefined method `allow' for #<Baz:0x8de6720>
# ./bar_spec.rb:5:in `allow_bar'
# ./bar_spec.rb:11:in `block (2 levels) in <top (required)>'
为什么我在一个类中的磕碰
该测试将其测试double定义为常规类,而不是使用rspec的“double”方法。这是因为测试double有一个线程。内部测试双是这样的代码:
if command == :close
# Note: Uses the old (rspec 2) syntax. Needs to be converted
# to rspec 3 syntax using the #allow method.
socket.stub(:getpeername).and_raise(RuntimeError, "Socket closed")
end
这可以防止错误地使用套接字会话被关闭后,被测代码。
私有解决方案
我可以给测试双接入在RSpec中,模拟调用私有API来#allow:
class Baz
RSpec::Mocks::Syntax.enable_expect self # Uses private API
def allow_bar(o)
allow(o).to receive(:bar)
end
end
这工作。然而,明确标记为RSpec的/嘲笑/ syntax.rb私有API:
# @api private
# Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc).
def self.enable_expect(syntax_host = ::RSpec::Mocks::ExampleMethods)
...
问题
在Rspec的3.1,有一个公共 API我可以用它来使期望类中可用的语法?
应该有注入'socket'到类的方式。然后,你将不再需要在课堂中使用'allow'。 AFAIK RSpec 3试图尽可能多地删除猴子补丁,这是一件好事。这听起来像是一个懒惰的回答,但是当你的代码很难测试时,大多数情况下这是你的代码有其他问题的迹象。 – 2014-09-05 19:44:26
@ p11y通常这是真的。我可能会在CR上发布完整的代码,看看其他人能否看到我看不到的更好的设计。 – 2014-09-05 19:55:25
@ p11y我开始编写CR问题,然后实现了一个更好的方法(在这种情况下,公开两个私有方法做了窍门,对类的API没有真正的破坏)。另一个问题在询问中回答。谢谢你的帮助。我仍然对这个问题的答案感兴趣,因为下一次我想做错了。 – 2014-09-06 00:28:45