8

JavaでJMockを使用してオブジェクト構築をモックする方法はありますか?

たとえば、そのようなメソッドがある場合:

public Object createObject(String objectType) {
    if(objectType.equals("Integer") {
        return new Integer();
    } else if (objectType.equals("String") {
        return new String();
    }
}

...テストメソッドでオブジェクト構築の期待をモックアウトする方法はありますか?

型をチェックするための余分なコードを用意するのではなく、特定のコンストラクターが呼び出されていることを期待できるようにしたいと考えています (私の例のように常に複雑で単純であるとは限らないため)。

したがって、代わりに:

assertTrue(a.createObject() instanceof Integer);

特定のコンストラクターが呼び出されることを期待できます。少しきれいにして、実際にテストされているものをより読みやすい方法で表現するためです。

単純な例で申し訳ありませんが、私が取り組んでいる実際の問題はもう少し複雑ですが、期待することで単純化できます。


もう少し背景について:

ラッパー オブジェクトを作成する単純なファクトリ メソッドがあります。ラップされるオブジェクトは、テスト クラス (既存のコード) で取得するのが難しいパラメーターを必要とする場合があるため、それらを構築することは困難です。

おそらく、私が実際に探しているものに近いのは、スタブするすべてのメソッドを指定せずに、(CGLib を使用して) クラス全体を一気にモックする方法はありますか?

したがって、モックはコンストラクターにラップされているため、明らかにメソッドを呼び出すことができます.JMockは各メソッドを動的にモックアウトできますか?

それはかなり複雑になるので、私の推測ではノーです。しかし、私が間違ったツリーを吠えていることを知っていることも価値があります:-)

4

6 に答える 6

7

私が考えることができる唯一のことは、ファクトリオブジェクトでcreateメソッドをオンにすることです。これは、モックするよりも重要です。

しかし、コンストラクター呼び出しをあざけるという点では、違います。モックオブジェクトはオブジェクトの存在を前提としていますが、コンストラクターはオブジェクトが存在しないことを前提としています。少なくとも、割り当てと初期化が同時に行われるJavaでは。

于 2008-09-18T12:30:31.370 に答える
4

jmockit はこれを行うことができます。

https://stackoverflow.com/questions/22697#93675​​で私の回答を参照してください

于 2008-09-18T15:54:04.360 に答える
1

残念ながら、私は間違った質問をした罪を犯していると思います。

テストしようとしていた単純なファクトリは次のようになりました。

public Wrapper wrapObject(Object toWrap) {
    if(toWrap instanceof ClassA) {
        return new Wrapper((ClassA) toWrap);
    } else if (toWrap instanceof ClassB) {
        return new Wrapper((ClassB) toWrap);
    } // etc

    else {
        return null;
    }
}

「new ClassAWrapper( )」が呼び出されたかどうかを調べる方法について質問していました。オブジェクト toWrap を分離テストで取得するのが困難だったからです。そして、ラッパー(それを呼び出すことができる場合でも)は、同じクラスを使用して異なるオブジェクトをラップし、異なるコンストラクターを使用するだけなので、ちょっと奇妙です[1]。もう少しうまく質問していたら、すぐに答えが返ってきたのではないかと思います。

「さまざまなテスト メソッドでテストしているインスタンスに一致するように Object toWrap をモックし、結果の Wrapper オブジェクトを調べて、正しい型が返されていることを確認する必要があります...そして、運が良ければそうする必要がないことを願っています世界をモックアウトして、さまざまなインスタンスを作成します ;-)"

私は今、当面の問題に対する大丈夫な解決策を持っています、ありがとう!

[1]これをリファクタリングする必要があるかどうかの問題を開くことは、私の現在の問題の範囲外です:-)

于 2008-09-18T13:53:14.010 に答える
0

依存性注入に精通していますか?

そうでない場合は、その概念について学ぶことで確実に利益が得られます。古き良きInversion of Control Containers とMartin Fowler による Dependency Injection パターンが良い入門書になると思います。

依存性注入 (DI) を使用すると、あらゆる種類のクラスを作成できる DI コンテナー オブジェクトが得られます。次に、オブジェクトは DI コンテナーを使用してクラスをインスタンス化し、DI コンテナーをモックして、クラスが期待されるクラスのインスタンスを作成することをテストします。

于 2008-09-18T12:36:29.123 に答える
0

依存性注入または制御の反転。

または、作成するすべてのオブジェクトに Abstract Factory デザイン パターンを使用します。単体テスト モードの場合は、何を作成しているかを通知する Testing Factory を挿入し、Testing Factory にアサーション コードを含めて結果を確認します (制御の反転)。

コードを可能な限りクリーンな状態に保つには、内部保護されたインターフェイスを作成し、インターフェイス (ファクトリ) を運用コードと共に内部クラスとして実装します。デフォルトのファクトリに初期化されたインターフェイスの静的変数タイプを追加します。ファクトリの静的セッターを追加すれば完了です。

テスト コード (同じパッケージ内にある必要があります。それ以外の場合、内部インターフェイスはパブリックである必要があります) で、アサーション コードとテスト コードを使用して匿名クラスまたは内部クラスを作成します。次に、テストでターゲット クラスを初期化し、テスト ファクトリを割り当て (注入)、ターゲット クラスのメソッドを実行します。

于 2008-09-18T12:57:27.017 に答える
-1

ないことを願っています。モックは、コンストラクターを持たないインターフェイスをモックすることになっています...メソッドだけです。

ここでのテストへのアプローチに何か問題があるようです。明示的なコンストラクターが呼び出されていることをテストする必要がある理由は何ですか?
ファクトリの実装をテストするには、返されたオブジェクトの型をアサートしても問題ないようです。createObject をブラックボックスとして扱います。それが返すものを調べますが、それがどのように行われるかを細かく管理しないでください。誰もそれを好きではありません:)

更新の更新:痛い! 絶体絶命の必死対策え?JMock がそれを許可するなら、私は驚かれることでしょう...私が言ったように、それはインターフェイスで動作します..具象型ではありません。そう

  • テスト ハーネスの下でこれらの厄介な入力オブジェクトを「インスタンス化可能」にするために、ある程度の努力を払ってください。あなたのアプローチでボトムアップしてください。
  • それが不可能な場合は、ブレークポイントを使用して手動でテストしてください (私はそれが悪いことを知っています)。次に、ソース ファイルの可視ゾーンに「Touch it at your own risk」というコメントを貼り付けて先に進みます。別の日に戦います。
于 2008-09-18T12:27:38.133 に答える