class A
def initialize
@x = do_something
end
def do_something
42
end
end
如何在调用原始实现之前在rspec中存根do_something
(从而将42分配给@x
)?当然,并没有改变实施。
答案 0 :(得分:22)
Here's the commit which adds the feature to rspec - 这是2008年5月25日。你可以这样做
A.any_instance.stub(do_something: 23)
然而,rspec的最新宝石版本(1.1.11,2008年10月)中没有此补丁。
This ticket表示由于维护原因他们将其拉出来,并且尚未提供替代解决方案。
此时看起来你不能做到这一点。你必须使用alias_method手动破解类。
答案 1 :(得分:16)
我在http://pivotallabs.com/introducing-rr/
上找到了这个解决方案new_method = A.method(:new)
A.stub!(:new).and_return do |*args|
a = new_method.call(*args)
a.should_receive(:do_something).and_return(23)
a
end
答案 2 :(得分:11)
我不知道如何在spec的模拟框架中执行此操作,但您可以轻松地将其替换为mocha以执行以下操作:
# should probably be in spec/spec_helper.rb
Spec::Runner.configure do |config|
config.mock_with :mocha
end
describe A, " when initialized" do
it "should set x to 42" do
A.new.x.should == 42
end
end
describe A, " when do_something is mocked" do
it "should set x to 23" do
A.any_instance.expects(:do_something).returns(23)
A.new.x.should == 23
end
end
答案 3 :(得分:5)
或RR:
stub.any_instance_of(A).do_something { 23 }
答案 4 :(得分:3)
在今天最新版本的RSpec中 - 3.5你可以:
allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
答案 5 :(得分:2)
我确实喜欢Denis Barushev的回答。而且我想建议只进行一次化妆改变,使new_method
变量不必要。 Rspec确实使用了存根方法,因此可以使用proxied_by_rspec__
前缀:
A.stub!(:new).and_return do |*args|
a = A.proxied_by_rspec__new(*args)
a.should_receive(:do_something).and_return(23)
a
end
答案 6 :(得分:2)
在RSpec 2.6或更高版本中,您可以使用
A.any_instance.stub(do_something: 23)
有关详细信息,请参阅the docs。 (感谢rogerdpack指出现在已经可以了 - 我认为它应该得到自己的答案)
答案 7 :(得分:0)
要存根实例方法,您可以执行以下操作:
before :each do
@my_stub = stub("A")
@my_stub.should_receive(:do_something).with(no_args()).and_return(42)
@my_stub.should_receive(:do_something_else).with(any_args()).and_return(true)
A.stub(:new).and_return(my_stub)
end
但正如pschneider指出的那样,只需返回新的42:
A.stub(:new).and_return(42)
或类似的东西。
答案 8 :(得分:0)
这是一个可能不是很优雅的想法,但基本上肯定会起作用:
创建一个继承要测试的类的小类,覆盖initialize方法,并在在初始化中创建存根后调用super
,如下所示:
it "should call during_init in initialize" do
class TestClass < TheClassToTest
def initialize
should_receive(:during_init)
super
end
end
TestClass.new
end
你去吧!我只是在我的一次测试中成功使用了它。
答案 9 :(得分:0)
rspec_candy gem附带一个stub_any_instance
辅助方法,适用于RSpec 1和RSpec 2。
答案 10 :(得分:-1)
在我的rspec(1.2.2)版本中,我可以这样做:
A.should_receive(:new).and_return(42)
我知道回复原版海报可能要迟到了,但无论如何我都会回答它以供将来参考,因为我带着同样的问题来到这里,但发现它正在研究最新的rspec版本。