Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby rspec:如何存根构造函数调用的实例方法?_Ruby_Rspec_Stub - Fatal编程技术网

Ruby rspec:如何存根构造函数调用的实例方法?

Ruby rspec:如何存根构造函数调用的实例方法?,ruby,rspec,stub,Ruby,Rspec,Stub,在调用原始实现(从而将42分配给@x)之前,如何在rspec中执行stub操作?当然,在不改变实现的情况下。我不知道如何在spec的模拟框架中做到这一点,但您可以轻松地将其替换为mocha来执行以下操作: class A def initialize @x = do_something end def do_something 42 end end 或与: -这是在2008年5月25日。有了这个你可以做到 stub.any_instance_of(A).do_

在调用原始实现(从而将42分配给
@x
)之前,如何在rspec中执行stub
操作?当然,在不改变实现的情况下。

我不知道如何在spec的模拟框架中做到这一点,但您可以轻松地将其替换为mocha来执行以下操作:

class A
  def initialize
    @x = do_something
  end

  def do_something
    42
  end
end
或与:

-这是在2008年5月25日。有了这个你可以做到

stub.any_instance_of(A).do_something { 23 }
然而,rspec的最新gem版本(1.1.112008年10月)中没有这个补丁

表示出于维护原因,他们将其拔出,但尚未提供替代解决方案

看起来你在这一点上做不到。您必须使用alias_方法或类似方法手动破解该类。

在我的rspec版本(1.2.2)中,我可以执行以下操作:

A.any_instance.stub(do_something: 23)

我知道回答原始海报可能已经太晚了,但我还是回答了它以备将来参考,因为我带着同样的问题来到这里,但发现它正在处理最新的rspec版本。

要存根实例方法,可以执行以下操作:

A.should_receive(:new).and_return(42)
但正如pschneider所指出的,只需在新的42上返回:
A.stub(:new.),并返回(42)
或类似的内容。

我在


我确实喜欢丹尼斯·巴鲁舍夫的回答。我只想建议做一个表面上的改变,这使得
新的\u方法
变量变得不必要。Rspec不使用存根方法,因此可以使用
proxied\u by\u Rspec\uuu
前缀访问它们:

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

这里有一个想法可能不是很优雅,但基本上肯定会奏效:

创建一个继承要测试的类的小类,重写initialize方法,并在initialize中创建存根后调用
super
,如下所示:


A.stub!(:new).and_return do |*args|
  a = A.proxied_by_rspec__new(*args)
  a.should_receive(:do_something).and_return(23)
  a
end
it“应该在初始化中的_init期间调用”do
类测试类<类测试
def初始化
应该接收(:在初始化期间)
超级的
结束
结束
TestClass.new
结束

就这样!我刚刚在我的一个测试中成功地使用了这个方法。

gem附带了一个
存根\u任意\u实例
助手方法,该方法在RSpec 1和RSpec 2.6或更高版本中都可以使用

it "should call during_init in initialize" do
  class TestClass < TheClassToTest
    def initialize
      should_receive(:during_init)
      super
    end
  end
  TestClass.new
end

有关更多详细信息,请参阅。(感谢您指出这现在是可能的-我认为它应该得到自己的答案)

在今天最新版本的RSpec-3.5中,您可以:

A.any_instance.stub(do_something: 23)

你建议的行为是不正确的。这是:do_something方法,它返回42,而不是初始值设定项。我认为关键是在您无法控制在测试中创建实例的情况下存根实例方法。另外,初始值设定项不返回42,它设置了一个实例变量:do_something方法返回42,需要存根。
A.stub(:new)。和_return(@my_stub)
每次都将返回实例存根,从而让您可以控制实例的创建。至于设置成员变量,我一直听说您不必担心模拟/存根中的内部问题,只需要公共接口。因此,只需为依赖于
@x
的方法返回正确的值即可。我可能认为这是一个非常好的想法,但它与我正在使用的RSpec版本不兼容。丹尼斯的回答确实有效。谢谢!是的,它非常依赖于“proxied_by_rspec_uu”名称前缀约定,该约定可能不是已发布API的一部分。哦,对不起,第二线不需要“.call”。顺便问一句,你用的是什么RSpec版本?@rogerdpack:的确,终于!“添加对any_instance.stub和any_instance.property的支持”。但是,如果您想将某些内容直接附加到new创建的实例上,您有什么想法吗?比如应该接收(:blah).正好是(5).次---你不希望任何对象都这样,只希望是那一次?@xaxxon一种方法是使用
any\u实例创建存根,然后构建对象,然后在再次调用构造函数之前使用
rspec\u reset
撤消所有存根。注
rspec_reset
没有文档记录,可能没有官方支持。在任何对象上调用它以删除该对象的存根
it "should call during_init in initialize" do
  class TestClass < TheClassToTest
    def initialize
      should_receive(:during_init)
      super
    end
  end
  TestClass.new
end
A.any_instance.stub(do_something: 23)
allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")