6

final メソッドの呼び出しをモックしようとしていますResourceBundle.getString()。PowerMock 1.4.12 と EasyMock 3.1 では、呼び出しはモックされていません。代わりに、「実際の」メソッドが呼び出されます。

私のテストクラス:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class) 
public class TestSuite {
    @Before
    public void setUp() throws Exception {
        ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class);
        expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue");
        PowerMock.replay(resourceBundleMock);

        beanBeingTested.setMessages(resourceBundleMock);
    }
    ...
}

BeanBeingTested のコード:

private ResourceBundle messages;
...
String label = messages.getString(BundleConstants.QUEUE);

エラーメッセージ:

java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue
at java.util.ResourceBundle.getObject(ResourceBundle.java:384)
at java.util.ResourceBundle.getString(ResourceBundle.java:344)
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87)

テスト ケースをステップ実行すると、デバッガーはbeanBeingTested.messages「クラス java.util.ResourceBundle の EasyMock」のタイプを表示するので、モックは正しく挿入されます。(また、セットアップ中getString()の呼び出し内への呼び出しにエラーはありません)。expect()

素敵なモックの代わりにプレーンなモックを使用すると、次のエラーが発生します。

java.lang.AssertionError: 
  Unexpected method call handleGetObject("Queue"): 
    getString("Queue"): expected: 1, actual: 0

私が間違っていることは何か分かりますか?

ありがとう。

4

3 に答える 3

3

EasyMock を使用してインスタンスを作成してい ます。代わりに、静的メソッドを操作する場合は、(PowerMock を使用して)クラスをモックする必要があります。

そのように動作するはずです (ただし、EasyMock 3.0 と PowerMock 1.5 でテスト済み):

@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class) 
public class TestSuite {
    @Before
    public void setUp() throws Exception {
        // mock the class for one method only
        PowerMock.mockStaticNice(ResourceBundle.class, "getString");

        // define mock-behaviour on the class, when calling the static method
        expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue");

        // start the engine
        PowerMock.replayAll();
    }
}

(この質問は数か月前のものであることは承知していますが、他の人には役立つかもしれませんが)

于 2013-01-29T14:04:23.140 に答える
1

使用してみてください:

@PrepareForTest({ResourceBundle.class, BeanBeingTested.class})

PrepareForTest で ResourceBundle のみを使用すると、単体テスト メソッドから直接呼び出されたときにモックが機能しますが、BeanBeingTested から呼び出されたときに実際のメソッドが使用されます。

この分野では、Powermock のドキュメントが不足しています。

于 2013-04-19T01:18:41.740 に答える
0

なぜわざわざリソースバンドルへの呼び出しをモックするのですか?一般的に、私はArrayList、DateなどのJavaの要点をあざけるのを避けようとします。リソースバンドル(およびMessageFormat.format())は、多かれ少なかれ同じカテゴリに分類されます。それらは一般的に基本的な文字列で動作し、これらのものが壊れているか、テストを壊すのに十分な動作を変更している場合、それは間違いなく私が知りたいことです:)

文字列を取得するだけです(おそらくUIで設定されようとしています。おそらく、後で設定されます。バンドルを編集してテストを中断したくないので、返された値をわざわざ主張しないでください。文字列が設定された場合模擬UIコンポーネントでは、これは、表示される特定の文字列を(おそらく)実際には気にしないという事実を正しく表現するanyObject(String.class)に適した場所です。

また、メッセージキーがないためにテストが失敗した場合にもメリットがあると思います。知りたいこと。

于 2012-08-23T17:27:18.547 に答える