32

minitest Rubyを使用して、関数が他の関数を適切に呼び出すかどうかをテストしたいのですが、ドキュメントassertからテストする適切なものが見つかりません。

ソースコード
class SomeClass
  def invoke_function(name)
    name == "right" ? right () : wrong ()
  end

  def right
    #...
  end

  def wrong
    #...
  end
end
テストコード:
describe SomeClass do
  it "should invoke right function" do
    # assert right() is called
  end

  it "should invoke other function" do
    # assert wrong() is called
  end
end
4

4 に答える 4

26

Minitestには、.expect :call何らかのメソッドが呼び出されたかどうかをチェックするための特別な機能があります。

describe SomeClass do
  it "should invoke right function" do
    mocked_method = MiniTest::Mock.new
    mocked_method.expect :call, return_value, []
    some_instance = SomeClass.new
    some_instance.stub :right, mocked_method do
      some_instance.invoke_function("right")
    end
    mocked_method.verify
  end
end

残念ながら、この機能は十分に文書化されていません。私はここからそれについて見つけました:https ://github.com/seattlerb/minitest/issues/216

于 2015-03-14T13:20:26.860 に答える
25

minitestではexpect、メソッドを使用して、次のようなモックオブジェクトで呼び出されるメソッドの期待値を設定します。

obj = MiniTest::Mock.new
obj.expect :right

パラメータと戻り値を使用して期待値を設定する場合は、次のようにします。

obj.expect :right, return_value, parameters

そして、そのような具体的なオブジェクトの場合:

obj = SomeClass.new
assert_send([obj, :right, *parameters])
于 2012-06-03T10:20:15.540 に答える
3

与えられた例によると、他のデリゲートクラスはなく、メソッドが同じクラスから適切に呼び出されていることを確認する必要があります。次に、以下のコードスニペットが機能するはずです。

class SomeTest < Minitest::Test
  def setup
    @obj = SomeClass.new
  end

  def test_right_method_is_called
    @obj.stub :right, true do
      @obj.stub :wrong, false do
        assert(@obj.invoke_function('right'))
      end
    end
  end

  def test_wrong_method_is_called
    @obj.stub :right, false do
      @obj.stub :wrong, true do
        assert(@obj.invoke_function('other'))
      end
    end
  end
end

アイデアは、単純な真の値を返すことによって[method_expect_to_be_called]をスタブ化することであり、スタブブロックでそれが実際に呼び出されて真の値を返すことを表明します。他の予期しないメソッドをスタブ化することは、それが呼び出されていないことを確認することです。

注:assert_sendは正しく機能しません。公式ドキュメントを参照してください。

実際、以下のステートメントは合格しますが、期待どおりに機能しているわけではありません。

assert_send([obj, :invoke_function, 'right'])
# it's just calling invoke_function method, but not verifying any method is being called
于 2015-08-13T10:10:58.427 に答える
0

最近、私は「stubberry」と呼ばれるこの種のアサーションを緩和するための宝石を作成しました。

ここでは、それを使用して必要な動作を管理する方法を説明します。

まず、質問に答える必要があります。

  • テストシーケンスを実行する前に、元のオブジェクトにアクセスできますか?

  • 確実に電話をかけることができる間接的な方法はありますか?つまり、アクセスできる他のオブジェクトに対していくつかのメソッド呼び出しがあるはずです。

  • メソッドを実際に呼び出す必要がありますか、それともprooperオブジェクトでスタブ化するか、呼び出し可能にすることができますか?

オブジェクトにアクセスでき、呼び出し可能オブジェクトを使用してメソッドをスタブできる場合:

obj.stub_must( :right, -> { stub_response } ) {
  ... do something 
}

オブジェクトにアクセスできるが、メソッドをスタブ化せず、メソッドが呼び出されたことを確認したい場合は、次のようにします。

  assert_method_called( obj, :right ) {
    .... do something with obj
  }

テストするオブジェクトにアクセスできない場合。ただし、他のオブジェクトメソッド呼び出しを使用して間接チェックを行うことができます。たとえば、「right」メソッドはAPI呼び出しの実行で終了します。

API.stub_must( :get, -> (path, params) {
  assert_equal( path, :expected_path )
  assert_equal( params, {} )
} ) do
  ... do something  
end
  

間接的なチェックを行うことはできません。


stunt_boudle = Obj.new

stunt_boudle.stub_must( :right, -> () {
  #do needed assertions
} ) do
   Obj.stub_must(:new, stunt_boudle) do 
     # do some integration testing 
   end
end 

# OR use assert_method_called the same way

また、idによるActiveRecordオブジェクトのスタブのクールなセットがあります。この場合、テストアクションの開始時にオブジェクトとそのActiveRecordオブジェクトにアクセスできないときにそれらを使用できます。

于 2022-01-18T07:55:14.177 に答える