2

テスト対象のクラスでプライベート メソッドを簡単に呼び出せるようにするユーティリティ メソッドを作成しようとしています。私が持っているのはこれです:

private Object callPrivateMethod(String methodName, Object subject, Object... parameters) {

    try {
        Class<?>[] paramTypes = new Class<?>[parameters.length];
        for (int index=0; index<parameters.length; index++) {
            paramTypes[index] = parameters[index].getClass();
        }
        Method method = subject.getClass().getDeclaredMethod(methodName, paramTypes);
        method.setAccessible(true);
        return method.invoke(subject, parameters);
    } catch (Exception e) {
        e.printStackTrace();
        fail(e.getMessage());
        return null;
    }
}

しかし、このコードを使用して呼び出そうとすると:

List<Session> sessions = new ArrayList<Session>();
// fill the array list
String sessionLines = (String) callPrivateMethod("getSessionsForEmail", emailSender, sessions);

私はこの例外を受け取ります:

java.lang.NoSuchMethodException: staffing.server.email.EmailSender.getSessionsForEmail(java.util.ArrayList)

EmailSender (テスト対象のクラス) のメソッド シグネチャは次のようになります。

private String getSessionsForEmail(List<Session> sessions) {
   //do stuff
}

リフレクションがメソッドを見つけられない理由を理解しようとしています。List と ArrayList がまったく同じクラスではないことに何か関係がありますか? もしそうなら、私は何ができますか?

4

5 に答える 5

6

プライベート メソッドを直接テストしないことをお勧めします。public および/または protected メソッドを介してそれらにアクセスすることにより、システムが本番環境でどのように動作するかをテストしています。このアプローチでは、パブリック/保護されたメソッドを介してデータのすべての組み合わせを送信することで、テスト カバレッジを管理することもできます。

保護されたメソッドは、テスト ソース フォルダーに同じパッケージ名を持つことでテストできます。

プライベート メソッドのテストが必須である場合は、リフレクションを自分で行う代わりに、Powermock などのモック ツールを使用できます。できれば Mockito を使用してください。これらのツールはどちらも JUnit とうまく統合されています。これは急な学習曲線ですが、投資する価値は十分にあります。詳細は次のとおりです。mockitoを使用したPrivateメソッドのテスト

于 2013-02-24T17:41:41.110 に答える
4

ArrayListコードは、 (の具体的なクラスsessions)を引数として取るメソッドを見つけようとします。ArrayListしかし、あなたのメソッドは引数として取りません。List引数として取ります。

パラメータの値に加えて、メソッドのパラメータのタイプを渡す必要があります。

または、コードをリファクタリングして、メソッドを保護またはパッケージ保護するか、パブリックメソッドとして別のコラボレーションクラスに配置することもできます。

于 2013-02-24T17:43:31.400 に答える
0

自分の実装で本当に成功したいのであれば、Javaでの型消去を見てみると便利かもしれないと思います。

それ以外の場合、Akber Choudhryが指摘したように、Mockitoにはorg.powermock.reflect.Whiteboxと呼ばれる優れたユーティリティパッケージが付属しています。私は間違いなくそれを使用します。

最後に、プライベートメソッドをテストすることは決してないとは言いませんが、テストする場合はよく考えてください。リフレクションベースのアプローチを維持することは、最も簡単なことではなく、エラーが発生しやすくなります。

于 2013-02-24T18:11:16.803 に答える
0

現在の推論では、プライベート メソッドをテストすべきではないとされています。それらは実装固有であり、それらを呼び出すメソッドを通じてテストする必要があります。または、それらを独自のクラスに抽出し、それを介してテストする必要があります。個別にテストする必要がある多くのことを行うプライベート メソッドがある場合、クラスはあまりにも多くのことを行うため、分割する必要があります。

このように見ることには多くの利点があります。少なくとも、クラスをハックしてテストする必要がなくなるわけではありません。

于 2013-02-24T17:48:32.387 に答える