2

パブリック メソッド呼び出しの場合、EasyMock の capture() を使用すると、メソッドに渡された引数をインターセプトして調べることができます。プライベート メソッド呼び出しの場合、PowerMock の expectPrivate を使用すると、プライベート メソッド呼び出しをモックできます。

これらを何らかの方法で組み合わせて、プライベート メソッド呼び出しに渡される引数を取得する方法はありますか? 例:

public class Program
{
    public FancyReturnType PublicMethod()
    {
        ArbitraryType localInstance = new ArbitraryType();
        localInstance.setFoo(somePrivateHelperMethod());
        localInstance.setBar(increasinglyComplexMagic());

        long aLongValue  = 11235L;
        // more variables, more work

        SomeType worker = privateHelperToIntercept(localInstance, aLongValue, otherVariables);

        if (worker.something)
        {
            return retVal.aFancyReturnType;
        }
        else
        {
            return retVal.anotherFancyReturnType;
        }
    }
}

この場合、呼び出しlocalInstanceによって消費されるオブジェクトを調べたいと思います。privateHelperToIntercept()

プライベート メソッド呼び出しをモックする例はたくさんあります。PowerMock はうまくexpectPrivate(partiallyMockedObject, "nameOfPrivateMethod", arg1, arg2)機能します。また、パブリック メソッド呼び出しに渡される引数をインターセプトする例も見つけました。Capture<Type> myTestCapture = new Capture<Type>()と組み合わせるsomeMockedObject.PublicMethod(capture(myTestCapture))

残念ながら、この 2 つを連携させることも、それらを組み合わせた例も見つけることができません。誰もこれを行う方法を見たことがありますか?

FWIW、私は Mockito がこれを行うことができると思いますが、ソース/ビルド/テスト システムには含まれていません。可能であれば、システムで新しいライブラリをサポートするプロセスを避けたいです。

4

2 に答える 2

1

localInstance への参照を取得する方法を尋ねている場合は、次のコードで十分です。

@PrepareForTest(Program.class)
public class Test {
    @Test
    public void testMethod() {
        ArbitraryType passedLocalInstance = new ArbitraryType();
        PowerMock.expectNew(ArbitraryType.class).andReturn(passedLocalInstance );

        //remainder of the test method

        assertEquals(14.2, passedLocalInstance .getValue());
    }
}

java は参照渡しであるため、passedLocalInstance がメソッド呼び出しに渡される引数になります。それはあなたの質問に答えましたか?

于 2013-04-10T21:08:29.440 に答える
0

new任意の型の単純な静的メソッドです。同じように処理します... メソッドでラップし、メソッドをスタブします。この場合、テストでモックを返す必要があり、そのオブジェクトとのすべての相互作用をテストできます (独自のテストを持つ必要がある作成中のオブジェクト内のコードに対するテストの依存関係を削除します)。

public Program {

    // your above code up to object creation
    ArbitraryType localInstance = createArbitraryType();
    // rest of your above code here


  ArbitraryType createArbitraryType() {
    return new ArbitraryType();
  }
}

あなたのテストで...

public class MyTest {
  TestableProgram extends Program {
    @Override 
    ArbitraryType createArbitraryType() {
      return this.arbitraryTypeMock; 
    }
  }

  private ArbitraryType arbitraryTypeMock;
  private TestableMyClass objectToTest = new TestableProgram();

  // rest of your tests...

}

あなたの制約を考えると、それが私のやり方です。

制約を少し曲げることができれば、private メソッドを緩めますが、テストを容易にするために、パッケージのデフォルトを優先して、通常は private を廃止しました。あなたのパッケージ内の人々が不正行為をしている場合、それは通常あなたのコードであるため、プライベートはとにかくあなた自身からあなたを保護しています. (しかし、それはあなたの質問に対する有効な答えではないことはわかっています...)。

于 2012-08-15T20:52:36.090 に答える