一緒にGuiceのとJMockを使用するための最良の方法は何ですか?

StackOverflow https://stackoverflow.com/questions/2044991

  •  20-09-2019
  •  | 
  •  

質問

私は、私は非常に厄介な手動注入を行い離れユニットテストからの層、(現在はJMockを使用して)モックを注入する必要がある主な理由は、プロジェクトにいくつかの依存性の注入を行うためのGuiceを使用して開始している。

私の質問は、モックを導入するための最良の方法は何かありますか?私が現在持っていることは、依存関係を満たすユニットテストで新しいモジュールを作成し、このようになりますプロバイダとそれらをバインドします:

public class JMockProvider<T> implements Provider<T> {
    private T mock;

    public JMockProvider(T mock) {
        this.mock = mock;
    }

    public T get() {
        return mock;
    }
}

コンストラクタでモックを渡すので、JMockのセットアップは次のようになります。

    final CommunicationQueue queue = context.mock(CommunicationQueue.class);
    final TransactionRollBack trans = context.mock(TransactionRollBack.class);
    Injector injector = Guice.createInjector(new AbstractModule() {
        @Override
        protected void configure() {
            bind(CommunicationQueue.class).toProvider(new JMockProvider<QuickBooksCommunicationQueue>(queue));
            bind(TransactionRollBack.class).toProvider(new JMockProvider<TransactionRollBack>(trans));
        }
    });
    context.checking(new Expectations() {{
        oneOf(queue).retrieve(with(any(int.class)));
        will(returnValue(null));
        never(trans);
    }});
    injector.getInstance(RunResponse.class).processResponseImpl(-1);

より良い方法はありますか?私はそれが自動魔法上記のようにローカルで作成されたモックを注入し、私はAtUnitはここに正しい答えであるなぜ説得力のある理由(他のいずれかを探していますどのように欠けているが、私は、AtUnitはこの問題に対処しようとしていることを知っていますテストを変更することなく、周りのDIとモックの枠組みを変更する能力より)、または手でそれを行うによりよい解決策があるかどうか。

役に立ちましたか?

解決

あなたはDIフレームワークかかわらず、モックを注入する必要はありません。私は非常に成功したのGuiceとJMockを使用していて、私のユニットテストは、Guiceのは、関連するものを参照しません。私はモックを使用してnull該当する場合に渡します。

DIは、注射を許可し、現在のクラスの依存関係を構築するので、あなたは(効果的依存関係グラフを停止する)を嘲笑クラスを追加したい場合はあなただけでそれを渡す必要があります。Misko Heveryのいずれかに記載されましたその範囲は、個々のユニットテストメソッドにローカライズされているので、ユニットテストはnewのとnull年代が散らばっされなければならないGoogleのテックトーク - 私は彼に同意する必要があります。

テストでGuiceのを使用する必要がある理由があり、それらが機能していない場合、つまり/統合テスト?

それは、インジェクタを除外した場合、

テスト作業ではないでしょうか?あなたのような何かにあなたのテストをリファクタリングできませんでした:

final CommunicationQueue queue = context.mock(CommunicationQueue.class);
final TransactionRollBack trans = context.mock(TransactionRollBack.class);

context.checking(new Expectations() {{
    oneOf(queue).retrieve(with(any(int.class)));
    will(returnValue(null));
    never(trans);
}});

RunResponse r = new RunResponse(queue, trans); // depending on the order
r.processResponseImpl(-1);

他のヒント

あなたは本当のユニットテストを行っていないように

あなたが言ったことから、それが聞こえます。クラスのユニット・テストを行う場合、あなただけの単一のクラスに焦点を当てます。あなたのユニットテストを実行すると、実行のみテストされるべき対象クラスを行使し、関連するクラスのメソッドを実行しないようにする必要があります。

JMock / Easymockは、あなたのクラスをユニットテストの達成を支援するためのツールです。彼らは、統合テストに有用ではありません。

ユニットテストの文脈では、GuiceのはJMock / Easymockと重なっています。 GuiceのはJMock / Easymockと同じ結果を達成するために(例えば@Injectなど)の注釈のすべての種類とそのコードを汚染することをユーザーに強制します。私は本当に強く、彼らがテストに役立つように、Guiceのに反対します。開発者が自分自身ではなく、JMock / EasymockのGuiceのを使用することを見つけた場合、それらが適切にどちらかの本当のユニットテストをしていないか、彼らはコントローラクラスをテストしてみます。

試験コントローラクラスは、ユニットテスト・レベルではなく、統合テストレベルで行われるべきではありません。統合テストのために、ジャカルタサボテンを使用すると、非常に便利です。統合テストでは、開発者は、Guiceのを使用する必要がない、それ故に可能なすべての依存関係を持っている必要があります。

結論として、私は製品のテストでGuiceのを使用するための任意の理由は表示されません。 GoogleのGuiceには異なるコンテキストが、テストで役に立つかもしれません。

Yishaiは、私はよりよい設計を駆動するをそれを修正するためには、はMartin Fowler氏によって導入された依存性注入パターンに入金する必要があります。 Guiceのは、あなたのコードが既にDIパターンを踏襲している場合に役立つツールです。 Guiceのは、あなたのより良い符号化には何も寄与しません。 Guiceのは、(注釈レベル)アドホック方法でDIを解決され、いずれかのDIフレームワークとして使用することが考慮されるべきではありません。これは、ばねによって、XMLベースのDIコンテナとGuiceのアノテーションによってベースDIコンテナとの間の大きな違いである。

私はあなたのコードを読むためにいくつかの時間を費やし、あなたがユニットは、あなたのクラスが不可能なテストと述べ理由だけで理解するために(私は通常はない)最初に投稿しました。私は最終的にあなたが直面している問題を理解しています。私が見たものから、ユニット・テスト・レベルである、あなたはそれは、Java EEサーバー内で実行されたときにコードの一部の実行フローを模倣しようとしました。それはあなたが捕まってしまった理由です。私はここにインセンティブがあるかわからないが、私はこれらの環境の依存関係のすべてを準備するあなたの努力が無駄にされようとしていることを怖い:(

ライティングユニットテストは、あなたが使用しているどんな技術から独立した「ビジネスロジック」をテストすることです。このビジネスロジックは、のQoS(Quality of Service)をの環境内で実行されなければならない旨の脇の要件があるかもしれません。この要件は、「技術的要件」です。あなたの例では、のCommunicationQueue にTransactionRollBack の大部分は "技術的要件" を満たすように機能しています。状況はあなたの「ビジネス要件」はこれらの環境のすべてのユニットに囲まれているです。あなたの「ビジネス要件」は、依存関係のない分離方法であるようにあなたがすべきことは、あなたのコードをリファクタリングしています。そして、あなたはこれらのメソッドのためのユニットテストを書きます。

私はまだあなたの機能テストを行っている検討してください。ユニット・テスト・レベルでの機能テストを行うことは非常に時間がかかり、どちらか、そのようなことをする価値はありません。私はそれが役に立てば幸い。

あなたはこれらの依存関係を歩くためにAOPを必要とするように

Yishaiは、聞こえます。 AspectJのとAspectWerkzは両方に有用なリソースです。しかし、AspectWekzは、JVMのホットスワップ技術を使用して、実行時にアスペクトクラスを編むのに非常に便利な機能を持っています。もちろん、これらのエンジニアリング作業は、ユニットテストのレベルで適用されるべきである。

私はユニットテストを行う際に、依存関係の解決に多くの労力を入れています。例えばJMock、EasyMock、Java EEのマイクロ容器、AspectJの、AspectWerkzなどのツールは、春IOCはDIの問題を解決するために使用することができます。これらのツールはいずれも、それらの生産コードでテスト意識を置く開発者を運転されていません。 Guiceのテストの意識のいずれかの種類からきれいにあなたのコードを維持するという概念に違反しているとあまりにも悪いです。そして、私は私のユニットテストで使用するツールとしてはカウントされません。

私はあなたの製品コードを@Inject注釈を脱いで、あなたに十分な理由を与えている願っています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top