class A
def initialize
@x = do_something
end
def do_something
42
end
end
do_something
元の実装が呼び出される前に(したがって42をに割り当てる前に)、rspecをスタブするにはどうすればよい@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")
私はデニス・バルシェフの答えが好きです。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
RSpec 2.6以降では使用できます
A.any_instance.stub(do_something: 23)
詳細については、ドキュメントを参照してください。(これが可能になったことを指摘してくれたrogerdpackに感謝します - 私はそれが独自の答えに値すると思いました)
これはあまりエレガントではないかもしれませんが、基本的には確実に機能するアイデアです。
テストするクラスを継承する小さなクラスを作成し、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つでこれをうまく使用しました。
インスタンスメソッドをスタブ化するには、次のようにします。
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を返すだけです。
rspec_candy gem には、RSpec 1 と RSpec 2 の両方で機能するヘルパー メソッドが付属していますstub_any_instance
。
私のバージョンのrspec(1.2.2)では、これを行うことができます。
A.should_receive(:new).and_return(42)
元のポスターに答えるのはおそらく遅いと思いますが、同じ質問でここに来たので、とにかく後で参照するために答えますが、最新のrspecバージョンで動作していることがわかります。