1

クラスのインスタンスメソッドがselfを返し、別のクラスインスタンスselfで初期化するようにしたいと思います。
しかし、私はこれを簡潔に指定する方法を見つけるのに苦労しています:

::Api.should_receive(:new).once do |arg|
  arg.should be_an_instance_of(::Cli)
end

この仕様を実行すると、予想どおり、次のメソッドがApiインスタンスではなくtrueで呼び出されるようになります。これは、ブロックの戻り値です。例:

class Cli
  def eg
    api = Api.new(self)
    api.blowup # undefined method for true
  end
end

スペックで別の呼び出しを呼び出さずにブロックがApiインスタンスを返すようにしたいのですが、Api.new(...)以下の例ではこれを行っています。rspec以外の読者は、明らかApi.new(...)に複数回呼び出されたときにスペックが合格する理由を疑問に思います。 。

誰かがこれを行うための最良の方法を提案できますか?

現在の解決策: これ::Api.new(...)は3回と呼ばれるようになります:1回は作成api、1回は作成cli、1回は作成start。それでも、1回の呼び出しの仕様は通過します。私はその理由とこれが正しいことを理解しているので、バグではありません。ただし、rspecに慣れていない読者がスキャンして、何Api.new度も呼び出されたような印象を与えない仕様が欲しいのですが。...once.and_return(api){...}また、機能しないことに注意してくださいapi。通過するには、ブロックが戻る必要があります。

let(:cli){ ::Cli.start(['install']) }
let(:start){ ::Cli.start(['install']) }
it 'is the API' do
  api = ::Api.new(cli)
  ::Api.should_receive(:new).once do |arg|
    arg.should be_an_instance_of(::Cli)
    api
  end
  start
end
4

1 に答える 1

1

元のメソッド()をローカル変数に保存し、newそれを使用しapiてブロック内から新しいメソッドを返すことができます。

original_method = ::Api.method(:new)
::Api.should_receive(:new).once do |arg|
  arg.should be_an_instance_of(::Cli)
  original_method.call(arg)
end

これにより、期待値が実行され、引数がのインスタンスであることを確認して::Cliから、元のメソッド(つまり、API)から値が返されます。

于 2012-11-25T13:48:06.203 に答える