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