class A
def initialize
@x = do_something
end
def do_something
42
end
end
do_something
在调用原始实现之前,如何在 rspec 中存根(因此将 42 分配给@x
)?当然,在不改变实现的情况下。
这是将功能添加到 rspec 的提交- 这是 2008 年 5 月 25 日。有了这个你可以做到
A.any_instance.stub(do_something: 23)
但是,最新的 rspec gem 版本(1.1.11,2008 年 10 月)中没有这个补丁。
这张票表明他们出于维护原因将其拉出,并且尚未提供替代解决方案。
看起来你现在做不到。您必须使用 alias_method 或类似的方法手动破解该类。
我在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
我不知道如何在规范的模拟框架中做到这一点,但您可以轻松地将其换成 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
或与RR:
stub.any_instance_of(A).do_something { 23 }
在今天最新版本的 RSpec - 3.5 中,您可以:
allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
我确实喜欢 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
在 RSpec 2.6 或更高版本中,您可以使用
A.any_instance.stub(do_something: 23)
有关更多详细信息,请参阅文档。(感谢rogerdpack指出现在这是可能的 - 我认为它应该得到自己的答案)
要存根实例方法,您可以执行以下操作:
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 指出的那样,只需在 new with: 上返回 42
A.stub(:new).and_return(42)
或类似的东西。
这是一个可能不是很优雅但基本上肯定会奏效的想法:
创建一个继承您要测试的类的小类,覆盖初始化方法并在初始化中创建存根super
后调用,如下所示:
it "should call during_init in initialize" do
class TestClass < TheClassToTest
def initialize
should_receive(:during_init)
super
end
end
TestClass.new
end
你去吧!我刚刚在我的一项测试中成功使用了它。
rspec_candy gem 带有一个在 RSpec 1 和 RSpec 2 中都可以使用的辅助方法。stub_any_instance
在我的 rspec (1.2.2) 版本中,我可以这样做:
A.should_receive(:new).and_return(42)
我知道回答原始海报可能为时已晚,但我还是回答了它以供将来参考,因为我带着同样的问题来到这里,但发现它正在使用最新的 rspec 版本。