_class A
def initialize
@x = do_something
end
def do_something
42
end
end
_
元の実装が呼び出される前に、rspecで_do_something
_をスタブするにはどうすればよいですか(したがって、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")
私はデニス・バルシェフの答えが好きです。そして、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
RSpec2.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が指摘したように、A.stub(:new).and_return(42)
またはその効果をもたらす何かを使用してnewで42を返すだけです。
rspec_candy gemには、RSpec1とRSpec2の両方で機能するstub_any_instance
ヘルパーメソッドが付属しています。
これはあまりエレガントではないかもしれませんが、基本的には確実に機能するアイデアです。
テストするクラスを継承する小さなクラスを作成し、initializeメソッドをオーバーライドして、次のように、初期化でスタブを作成したsuper
afterを呼び出します。
it "should call during_init in initialize" do
class TestClass < TheClassToTest
def initialize
should_receive(:during_init)
super
end
end
TestClass.new
end
そして、あなたは行きます!私はこれを私のテストの1つでうまく使用しました。