単体テストはどのように書くのでしょうか?
JUnit の概要
基本的に、どの言語やフレームワークにも、Java の JUnit、Scala の ScalaTest、Python の Unittest、JavaScript の Jest など、優れた単体テスト フレームワークとツールがあります。上記の例は JUnit に基づいています。以下で JUnit について簡単に紹介します。
JUnit の @Test アノテーションが付けられた各メソッドはテストです。@Ignore はテストを無視できます。@Before、@BeforeClass、@After、@AfterClass では、初期化やリソースの解放など、テスト実行の前後にいくつかの一般的な操作を挿入できます。
JUnit は、assertEquals に加えて、他の多くの Assert メソッドもサポートしています。たとえば、assertNull、assertArrayEquals、assertThrows、assertTimeout などです。さらに、Spring の Assert や AssertJ などのサードパーティの Assert ライブラリを使用することもできます。
JUnit は、一般的なコード ロジックのテストに加えて、例外テストや時間テストも実行できます。例外テストは、特定のコードが指定された例外をスローする必要があることをテストすることです。時間テストは、コードの実行時間が特定の範囲内であることをテストします。
グループテストも可能です。例えばcontractTest、mockTest、unitTestに分けて、あるグループのテストをパラメータで指定することができます。
ここではあまり紹介しませんが、JUnit について詳しく知りたい場合は、Geek Academy の JUnit チュートリアルやその他の資料を参照してください。他の単体テスト フレームワークの基本機能は似ています。
テスト Double を使用する
狭い単体テストでは、単体のみをテストします。一般化された単体テストを作成したとしても、他のクラスのメソッド、サードパーティのサービス呼び出し、データベース クエリなどの他のモジュールに依存する可能性があり、テスト対象のシステムやモジュールを完全にテストすることが不可能になります。都合よく。次に、テスト Double を使用する必要があります。
よく勉強すると、Double というテストは、ダミー、フェイクなど、さまざまな種類に分かれています。ただし、明確にする必要があるのは、スタブとモックの 2 つのカテゴリだけだと思います。
スタブ
スタブは、事前定義されたデータを含むオブジェクトであり、テスト中に呼び出し元に返されます。スタブは、実際のデータを返したくない、または他の副作用を引き起こしたくないシナリオでよく使用されます。
契約テストによって生成され、Spring Cloud stubrunner を通じて実行できる Stub Jar はスタブです。スタブにプリセットされた偽のデータを返させることができ、単体テストでこれらのデータを信頼してコードをテストできます。たとえば、ユーザーがスタブにクエリを実行して、パラメーター内のユーザー ID に従って認証されたユーザーと認証されていないユーザーを返すことができ、その後、これら 2 つのケースで呼び出し元の処理ロジックをテストできます。
もちろん、スタブはリモート サービスではなく、別のクラスである可能性があります。そのため、インターフェイスに対してプログラミングする必要があるとよく言われます。これにより、インターフェイスのスタブ実装を簡単に作成して特定のクラスを置き換えることができるからです。
public class StubNameServiceimplement NameService {
public String get(String userId) {
return ""ユーザー名を模擬"";
}
}
パブリック クラス UserServiceTest {
// UserService は NameService に依存しており、その get メソッドを呼び出します
@Inject
プライベートUserService userService;
@テスト
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
userService.setNameService(new StubNameService());
String testName = userService.getUserName(““SomeId””);
Assert.assertEquals(""模擬ユーザー名"", testName);
}
}
ただし、このように多数のスタブを実装するのは非常に面倒ですが、現在はさまざまなモックツールがあるため、自分でスタブを作成する必要はありません。
モック
モックとは、呼び出し情報を記録できるオブジェクトを指します。テスト アサーションでは、モックが期待どおりに呼び出されることを確認できます。
モックとスタブの違いは、スタブは一部のデータのみを提供するか、検証を実行しないか、または状態に基づいて一部の検証のみを実行することです。モックはスタブの実行に加えて、呼び出し動作に基づいて検証を実行することもできます。たとえば、Mock は、Mock インターフェイスが正確に 2 回呼び出され、呼び出しのパラメータが期待値であることを検証できます。
Java で最もよく使用されるモック ツールは Mockito です。簡単な例を見てみましょう。次の UserService は NameService に依存しています。UserService をテストするときは、NameService を分離する必要があるため、Mock NameService を作成して UserService に注入できます (Spring では、@Mock と @InjectMocks の 2 つのアノテーションを使用するだけで完了します)。
パブリック クラス UserServiceTest {
@InjectMocks
プライベートUserService userService;
@モック
プライベート NameService ネームサービス;
@テスト
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
Mockito.when(nameService.getUserName(““SomeId””)).thenReturn(““模擬ユーザー名””);
String testName = userService.getUserName(““SomeId””);
Assert.assertEquals(""模擬ユーザー名"", testName);
Mockito.verify(nameService).getUserName(““SomeId””);
}
}
上記の最後の行は、nameService の getUserName がパラメーター ""SomeId"" を使用して呼び出されることを確認していることに注意してください。Mockito の詳細については、Mockito のドキュメント (
http://static.javadoc.io/org.mockito/mockito-core/2.9.0/org/mockito/Mockito.html)。
契約テスト
コントラクト テストでは、サービスごとにスタブが生成され、呼び出し元の単体テスト/統合テストに使用できます。たとえば、予約サービスの予約操作をテストする必要があります。予約操作では、ユーザー サービスを呼び出して、医師の資格があるかどうかなど、ユーザーの基本情報を確認します。
したがって、異なるユーザー ID を渡すことで、コントラクト スタブが異なる状態のユーザー データを返せるようにすることで、異なる処理手順を検証できます。たとえば、通常の予約フローのテスト ケースは次のようになります。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest@AutoConfigureStubRunner(repositoryRoot=“http://<nexus_root>””,
ids = {""com.xingren.service:user-client-stubs:1.0.0:stubs:6565""})public class BookingTest {
// BookingServiceはユーザーサービスを呼び出し、医師の認証ステータスを取得した後に別の処理を実行します
@Inject
プライベート BookingService 予約サービス;
@テスト
public void testBooking() {
BookingForm フォーム = 新しい BookingForm(
1,// 医師 ID
1 // スケジュールID
1001);// 患者 ID
BookVO res =bookingService.book(form);
assertTrue(res.id > 0);
assertTrue(res.payStatus == PayStatus.UN_PAY);
}
}
上記の AutoConfigureStubRunner アノテーションは、ユーザー サービス Stub を設定して開始するためのものであることに注意してください。もちろん、テストする場合は、サービス呼び出しインターフェイスの BaseUrl を http://localhost:6565 に設定する必要があります。契約テストの詳細については、「マイクロサービス環境での統合テストの探索」の記事を参照してください。
TDD
簡単に言えば、テスト駆動開発 (TDD) です。TDDは見た目ほど美しくないという記事を左耳ネズミさんが書いていたので、その紹介文をそのまま引用させていただきました。
開発プロセスは、機能要件のテストケースから始まり、最初にテストケースを追加し、次にすべてのテストケースを実行して問題がないかどうかを確認し、その後、テストケースでテストする機能を実現し、その後テストケースを実行します失敗するケースがあるかどうかを確認し、コードをリファクタリングして、上記の手順を繰り返します。
実際、厳密な TDD プロセスはあまり実用的ではなく、左耳マウス自体も重要です。ただし、明確なインターフェイス定義を持つモジュールの場合は、最初に単体テストを作成してから実装コードを作成することが依然として有益です。目標が明確で、すぐにフィードバックを得ることができるからです。
記事の出典: ネットワークの著作権は原作者に帰属します
上記のコンテンツは営利目的ではありません。知的財産権に関する問題が含まれる場合は、編集者にご連絡ください。すぐに対処します。