2

invokeMethod()引数で呼び出しているメソッドに明示的に名前を付けたくありません。Powermock は、invokeMethod()渡されたパラメーターに基づいてメソッドを推測するオーバーロードを提供します。

invokeMethod(Object instance, Object... arguments)

私が直面している問題は、最初のパラメーターのタイプがString. invokeMethod()これにより、署名付きで が呼び出されます。

invokeMethod(Object instance, String methodToExecute, Object... arguments)

これがテストのモデルです...

@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";
    String firstArgument = "123A48"; 

    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, firstArgument, AnEnum.TypeA);
    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);
}

これは私にエラーを与えます、

org.powermock.reflect.exceptions.MethodNotFoundException: No method found with name '123A48' with parameter types: [ AnEnum ] in class TheClassBeingTested.`

最初のパラメーターのタイプを に変更して動作させましたObjectが、これは私には汚いと感じます。

@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";
    Object firstArgument = "123A48"; 

    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, firstArgument, AnEnum.TypeA);
    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);
}

メソッド名を呼び出しStringにハードコーディングせずに、最初の引数として型を渡す正しい方法はありますか? invokeMethod()これに対処するPowermockのドキュメントやフォーラムには何も見つかりませんでしたが、それほど珍しいことではありません.

4

1 に答える 1

3

実際に行う必要があるのは、TheClassBeingTested.java を確認することです。エラー メッセージは、Whitebox.invoke メソッドがリフレクションによって作成している TheClassBeingTested で "123A48" という名前のメソッドを見つけられないことが問題であることを示しています。この場合、あなたが選択したと私が思うinvokeMethodは、パラメータ(Object classUnderTest、String methodName、Object...parameters)を探しています。

次のようなことを試してください:

public class TheClassBeingTested {
    private String foo;

    public void setFoo(String fooValue) {
        foo = fooValue;
    }

    public String getFoo() {
        return foo;
    }

}

次に、次のように Whitebox でテストできます。

public class TheClassBeingTestedTester {

    @Test
    public void thisIsATest() throws Exception {
        TheClassBeingTested toBeTested = new TheClassBeingTested();
        String theMethodToTest = "setFoo";
        String expectedFooValue = "foo bar baz";

        ReturnType returnedTypeValue = Whitebox.invokeMethod(toBeTested, theMethodToTest, expectedFooValue);
        String actual = returnedTypeValue.getTestedField();
        assertEquals("Expected " + expected + " but found " + actual, expected, actual);
     }
}

それが役立つことを願っています。

...以下の編集された応答

他の開発に取り組んでいる間、あなたの質問を注意深く読まなかったので、私はポイントを逃しました。

この場合、呼び出しメソッドのあいまいさの問題を回避するために、テストに次の変更を加えます。

@Test
public void thisIsATest() throws Exception{
    TheClassBeingTested myClassInstance = new TheClassBeingTested();
    String expected = "60";

    Object[] parameters = new Object[]{"123A48", AnEnum.TypeA};

    ReturnType returnedTypeValue = Whitebox.invokeMethod(myClassInstance, parameters);

    String actual = returnedTypeValue.getTestedField();
    assertEquals("Expected should be actual when AnEnum is TypeA", expected, actual);

}

このようにして、曖昧さが取り除かれ、invokeMethod(Object instance, Object... arguments) は、メソッド シグネチャがコンパイラに期待するように指示するオブジェクトの配列のみを認識します。String はオブジェクトですが、メソッド シグネチャ リフレクションでは、java.lang.reflect は、使用したいものよりも使用するように指示しようとしていると感じられる 2 番目のシグネチャに従います。

この回答があなたの要求をよりよく満たすことを願っています。

于 2015-09-24T20:04:47.610 に答える