31
class A
  def initialize
    @x = do_something
  end

  def do_something
    42
  end
end

do_something元の実装が呼び出される前に(したがって42をに割り当てる前に)、rspecをスタブするにはどうすればよい@xですか?もちろん、実装を変更することなく。

4

11 に答える 11

22

rspec に機能を追加するコミットは次のとおりです。これは 2008 年 5 月 25 日のものです。

A.any_instance.stub(do_something: 23)

ただし、rspec の最新の gem バージョン (1.1.11、2008 年 10 月) には、このパッチが含まれていません。

このチケットには、メンテナンス上の理由で削除したことが記載されており、代替ソリューションはまだ提供されていません。

現時点ではできるようには見えません。alias_method などを使用して手動でクラスをハックする必要があります。

于 2008-11-25T21:44:50.403 に答える
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
于 2009-12-25T11:47:51.527 に答える
11

スペックのモックフレームワークでそれを行う方法はわかりませんが、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
于 2008-11-25T03:50:18.683 に答える
5

またはRRを使用:

stub.any_instance_of(A).do_something { 23 }
于 2008-11-25T04:16:50.067 に答える
3

今日の RSpec の最新バージョン - 3.5 では、次のことができます。

allow_any_instance_of(Widget).to receive(:name).and_return("Wibble")
于 2016-07-14T09:39:52.203 に答える
2

私はデニス・バルシェフの答えが好きです。new_methodそして、変数を不要にする外観上の変更を 1 つだけ提案したいと思います。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
于 2010-04-22T12:45:47.867 に答える
2

RSpec 2.6以降では使用できます

A.any_instance.stub(do_something: 23)

詳細については、ドキュメントを参照してください。(これが可能になったことを指摘してくれたrogerdpackに感謝します - 私はそれが独自の答えに値すると思いました)

于 2012-08-21T12:31:14.393 に答える
0

これはあまりエレガントではないかもしれませんが、基本的には確実に機能するアイデアです。

テストするクラスを継承する小さなクラスを作成し、initializeメソッドをオーバーライドして、次のように、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

そして、あなたは行き​​ます!私は自分のテストの1つでこれをうまく使用しました。

于 2012-05-01T18:24:59.057 に答える
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が指摘したように、新しい A.stub(:new).and_return(42)ものに42を返すだけです。

于 2009-10-11T05:25:56.833 に答える
0

rspec_candy gem には、RSpec 1 と RSpec 2 の両方で機能するヘルパー メソッドが付属していますstub_any_instance

于 2012-06-10T08:50:28.810 に答える
-1

私のバージョンのrspec(1.2.2)では、これを行うことができます。

A.should_receive(:new).and_return(42)

元のポスターに答えるのはおそらく遅いと思いますが、同じ質問でここに来たので、とにかく後で参照するために答えますが、最新のrspecバージョンで動作していることがわかります。

于 2009-08-22T17:10:29.260 に答える