springframeworkを使用した不十分なjunitテストには、壊れやすいthread.sleep()呼び出しがあります。直し方?
-
09-10-2019 - |
質問
私は最近、いくつかの深刻なジュニットテストの問題を抱えているグループに参加しました。 1つの問題は、8分間のテストです!テストにはいくつかのセクションがあります。それぞれがorg.springframework.context.applicationeventpublisher.publishevent()に電話をかけます。
このアプローチにはいくつかの明らかな問題があります。スレッドのタイミングは壊れやすいです。
忙しいマシンでテストが失敗することがあります。と
失敗しない場合、テストには時間がかかりすぎます。
これらのイベントにテストにアクセスできるプールは、イベントカスケードがQuiescedになっているかどうかを確認するための呼び出しがありますか?
解決
デフォルトを上書きすることができます applicationEventMulticaster
このBean IDをアプリケーションコンテキストに追加します。
デフォルトの代わりに SimpleApplicationEventMulticaster
, 、この豆にtaskexecutorを設定して、複数のスレッドで非同期に公開するイベントを実行できます。
または、独自のマルチカスターを実装することもできます。これは、どのイベントリスナーが非常に長くかかったか、ブロックしていたか、どのくらいの期間、どのイベントでかかっていましたか。それはあなたが8分間のテストケースの本当の問題を追跡するのに役立ちます。
興味深いことに、simpleapplicationeventMulticasterのJavadocは、springでアプリケーションContextを使用しているときにデフォルトで使用されます。
デフォルトでは、すべてのリスナーが呼び出しスレッドで呼び出されます。 これにより、アプリケーション全体をブロックする不正なリスナーの危険が可能になります, 、しかし、最小限のオーバーヘッドを追加します。代替のtaskexecutorを指定して、リスナーを異なるスレッドで実行すること、たとえばスレッドプールから実行します。
他のヒント
言及する価値は、実際に外部サービスを呼び出すテストコードは、単体テストではなく統合テストであることです。ここで本当にユニットテストをしている場合は、それらの呼び出しを模擬に置き換える必要があります。そうすれば、ビジネスロジックに返された値をより適切に制御し、特定の条件をテストできます。また、あなたが見たように、これはほとんどすべてが外部(非コード)の状況による誤検知を排除します。明らかに、これらのテストは失敗しておらず、使用する施設はISです。
私は(意図的に)春を避けているので、詳細を手伝うことができるかどうかはわかりませんが、睡眠の問題を見るだけで、あなたは次のようなものを使用できます WaitFor
Tempus-Fugit(恥知らずなプラグ)で投票する Condition
「眠りと希望」ではなく。それは理想的ではなく、通常、テスト方法の変更(前に提案されたように)が望ましいですが、レース条件 /フレーク状のテストを避け、一般的にテストをスピードアップする可能性が高い「待機」を得ることができます。
プロジェクトをご覧ください ドキュメンテーション 詳細については、便利だと思う場合は投稿してください!