3

execute私は Struts2 フレームワークを使用しており、以下のメソッドを単体テストしたいと考えています。

public String execute() {
    setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));
    setUserPrincipal(); //fetches attribute from request and stores it in a var
    setGroupValue(); //
    setResults(getMyDao().getReportResults(getActionValue(), getTabName());
    setFirstResultSet((List) getResults()[0]);
    setSecondResultSet((List) getResults()[1]);
    return SUCCESS;
}

ご覧のとおり、ほとんどのロジックはデータベースに関連しています。では、この機能の単体テストを行うにはどうすればよいでしょうか。HTTPServletRequest内部にいくつかのリクエスト変数を使用して をモックして、単体テストを行いたいと思います。

私の質問は次のとおりです。

  • ブラウザから来ているかのようにリクエスト変数を偽装/モックするにはどうすればよいですか
  • 単体テストで実際の DAO を呼び出して、データが戻ってくることを確認する必要がありますか?
  • その場合、jndi プール設定がアプリケーション サーバーに存在するため、DAO はサーバーに関連付けられているため、単体テストから DAO を呼び出すにはどうすればよいですか。

これを実際に達成する方法を示す本/記事をいただければ幸いです。

4

3 に答える 3

6

あなたが私たちに示したコードはあなたの質問に完全に答えるのに十分ではありません。

1行ずつ

setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));

これは静的な方法を使用しているため、最も難しい行です。どのように機能するかを確認する必要がありますApplicationInitializer。理想的な世界では、getApplicationContext()メソッドはのモックを返す必要がありApplicationContextます。MyDAOこのモックは、。のときに戻るはずgetBean("MyDAO")です。は、他のすべてのモックフレームワークと同様に、これを完全に処理できます。


setUserPrincipal(); //fetches attribute from request and stores it in a var

リクエストはどこから来ますか?アクションクラスに注入されていますか?その場合は、モックされたリクエストオブジェクトを挿入するだけMockHttpServletRequestです。


setGroupValue(); //

同上?この方法が実際に何をするのか、詳細を教えてください。


setResults(getMyDao().getReportResults(getActionValue(), getTabName());

以前に作成したモックはgetReportResults()、指定された引数で呼び出されたときに何かを返す必要があります。


setFirstResultSet((List) getResults()[0]);
setSecondResultSet((List) getResults()[1]);

以下のメソッドは、アクションクラスにいくつかのフィールドを設定していると思います。モックから返されるものを完全に制御できるためgetReportResults()、これは問題ではありません。


return SUCCESS;

SUCCESS実行の結果であるかどうかを主張できます。


今一般的に

ブラウザから送信されたかのようにリクエスト変数を偽造/モックするにはどうすればよいですか?

上記を参照してください。Springにはモックが組み込まれています。

ユニットテストで実際のDAOを呼び出し、データが戻ってくることを確認する必要がありますか?

ユニットテストが実際のDAOを呼び出す場合、それはもはやユニットテストではありません。統合テストです。

その場合、jndiプール設定はアプリケーションサーバーに存在するため、DAOはサーバーに関連付けられているため、単体テストからDAOを呼び出すにはどうすればよいですか。

これは、統合テストを行っていることを意味します。その場合は、サーバーでテストを実行できるようにする必要があります。DataSource別の場所からフェッチするようにアプリケーションを構成する必要があります。


最後の注意

本質的には、Strutsアクションクラスにすべてのモックを注入する必要があります。呼び出し時に任意の値を返すようにモックに指示できます。次に、を呼び出した後execute()、指定されたメソッドが呼び出され、フィールドが設定され、結果の値が正しいことを確認できます。これをいくつかのテストに分割することを検討してください。


コードレビュー

  • Struts2はSpringと完全に統合されています。その機能を利用すると、Springコンテナは自動的MyDAOにアクションクラスに注入されます。最初の行は廃止されます。
于 2012-05-23T18:55:13.873 に答える
1

このコードは、意図したとおりに(つまり、依存性注入フレームワークとして)Springを使用する代わりに、ファクトリとして使用するため、単体テストが困難です。依存性注入は、テストが難しいこの種のBeanルックアップを回避するために正確に使用されます。DAOをオブジェクトに注入する必要があります。そうすれば、オブジェクトを単体テストするときにモックDAOを注入できます。

また、このロジックはデータベースとはまったく関係ありません。DAOには、データベース関連のロジックが含まれています。このアクションDAOを使用するため、DAOは別の単体テストになります(独自の単体テストでテストする必要があります)。したがって、このメソッドの単体テストを行うには、模擬DAOを注入する必要があります。

最後に、このメソッドはHttpServletRequestを(少なくとも直接ではなく)使用しないため、偽のリクエストを使用する必要がある理由がわかりません。リクエストを使用するsetXxxメソッドをモックすることができます。

于 2012-05-23T18:53:57.037 に答える
0
  1. を単純にモックするのではなくHTTPServletRequest、アプリケーション自体への実際の自動化されたターゲット リクエストをモックするのはどうですか? まさにそれを可能にするSeleniumをチェックしてください。

  2. DAO (統合テスト) をテストするには、HSQLDBを使用してメモリ内にデータベースを作成できます。これにより、テストからオブジェクトを作成/削除し、それらが適切に永続化/取得されることを確認できます。HSQLDB の利点は、実際のデータベースよりもはるかに高速にテストを実行できることです。コードをコミットするときが来たら、実際のデータベースに対してテストを実行できます。通常、これを容易にするために、IDE でさまざまな実行構成をセットアップします。

  3. 注入された daos をテストで使用できるようにする最も簡単な方法は、単体テスト クラスを拡張できるようにすることAbstractJUnit4SpringContextTestsです。次に、@ContextConfiguration注釈を使用して複数の xml アプリケーション コンテキスト ファイルを指すことができます。または、注釈ベースの構成を使用する場合は、<context:annotation-config />宣言を含むコンテキスト ファイルを指すことができます。

于 2012-05-23T19:01:49.087 に答える