REST Webサービスを単体テストするにはどうすればよいですか?


16

ユニットテストは初めてで、DBを呼び出してDTOを設定するREST Webメソッドが1つあります。擬似コードは

public object GetCustomer(int id)
{
  CustomerDTO objCust = //get from DB
  return objCust;
}

私の疑問は、含まれるこれらのメソッドとテストのタイプ(Integration / Unit)のテストの書き方です。単体テストの場合、DBにアクセスする必要がありますか。そうであり、顧客IDを渡してアサーションをほとんど行わない場合、データが最終的に変更されて失敗する可能性があります。

ここでこれらの概念を理解している何かが欠けていると思います。


5
投稿したコードでは、テストすることが次のとおりです。(1)intをパラメーターとしてGetCustomerを呼び出すことができます。(2)CustomerDTOオブジェクトを返しますか?(3)そのオブジェクトは、期待どおりにDBから取り込まれますか。(4)有効な顧客に対応しないintで呼び出された場合、予期される動作が発生しますか?まだRESTとは関係ありません。RESTfulリクエストに応答するコードを作成する準備ができたら、そのテストを作成します。
-DavidO

@DavidO:「そのオブジェクトは期待どおりにDBから読み込まれますか?」明らかにユニットテストではありません(OPのコードに関して)。それは統合テストです。
Flater

はい。それで合っています。戻ってコメントを変更して、統合テストでDBコンポーネントを検証し、それ以外の場合はそれをモックすることができるとしたら、その編集を行いますが、5分間のコメントの編集ウィンドウとコメントが6数年前。:)
DavidO

回答:


18

単体テストでは、データベースでテストすることは期待されていませんが、少なくとも、単体テスト用に準備していないデータベースではテストしないでください。データベースを使用したテスト、およびそのため、アプリケーションのさまざまなレイヤーを同時にテストすることは、一般に統合テストと見なされます。単体テストでは、メソッドが実行すること、さまざまなパラメーターに応じてメソッドが返すこと、および失敗する場合(または失敗しない場合)のみをテストすることになっています。

メソッドでは、他のクラスからXメソッドを呼び出すことが非常に期待されています。これらのXメソッドをテストしていないので、これらのメソッドをモックする必要があります。

Javaでコードを記述していると思います。その場合、Mockitoのような素晴らしいモックフレームワークがあり、これが役立つかもしれません。モックフレームワークを使用するかどうかはあなたの選択ですが、私は彼らが多くの時間を節約すると言うだけで、少なくとも私が言及したものは本当に複雑ではありません。

独自のモックを作成して実験したい場合は、次のCustomerRepositoryクラスがあるとします。

public class CustomerRepository {
 public CustomerDTO getCustomer(int id) {
   ...
 }
}

CustomerRepository次の方法で、モックされたダーティクラスを作成できます。

public class MockedCustomerRepository extends CustomerRepository {
 public boolean bThrowDatabaseException;
 public boolean bReturnNull;
 public boolean bReturnCustomerWrongId;
 public boolean bReturnCustomerWithId;
 public CustomerDTO getCustomer(int id) {
  if(bThrowDatabaseException) { 
    throw new DatabaseException("xxx"); 
  } else if(bReturnNull) { 
    return null; 
  } else if(bReturnCustomerWrongId) { 
    throw new CustomerNotExistException(id);
  } else if(bReturnCustomerWithId) { 
    return new CustomerDTO(id); 
  }
 }
}

次に、テストケースで、基本的にの「標準」インスタンスをCustomerRepository、インスタンスのさまざまな結果についてメソッドをテストできる模擬インスタンスに置き換えますgetCustomer

public class CustomerRestTest {
  public void testGetCustomer_databaseFailure() {
    MockedCustomerRepository dto = new MockedCustomerRepository();
    dto.bThrowDataBaseException = true;
    yRestClass rest = new MyRestClass();
    rest.dto = dto;
    rest.getCustomer(0);
    // depending on what you do in your getCustomer method, you should check if you catched the exception, or let it pass, etc.. Make your assertions here

  public void testGetCustomer_customerNotExist() {
    // etc.
  }
}

一般に、すべてのテストメソッドは1つのことのみをテストする必要があります。これにより、テストを小さくし、1つのタスクに集中することができます。

繰り返しますが、模擬クラス全体を書くのは、ご覧のとおり時間がかかります。モックフレームワークを使用することを検討してください。コードの記述が少なければ少ないほど、エラーが少なくなりますよね?例外をスローするメソッド、または特定のパラメーターに指定された値を返すメソッドのモックは簡単で、2行または3行かかります(少なくともmockitoを使用)

RESTメソッドのテストに役立つことを願っています。


4
通常、DTOクラス内にロジックはありません。特に、データストレージと対話するロジックはありません。
JustAnotherUserYouMayKnowOrNot

1
これはほんの一例ですが、あなたは絶対に正しいです。理論に合うように例を変更します。
ジャレイン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.