web-dev-qa-db-ja.com

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

ユニットテストは初めてです。REST DBを呼び出し、DTOにデータを入力するだけのWebメソッドです。疑似コードは

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

私の疑問は、これらのメソッドのテストをどのように記述し、テストのタイプ(統合/ユニット)を含めるかです。単体テストの場合、DBにアクセスする必要がありますか。それがあり、私が顧客IDを渡していくつかのアサーションを実行すると、データが最終的に変更されて失敗する可能性があります。

これらの概念を理解するためにここで何かが足りないと思います。

16
Sunny

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

あなたのメソッドでは、他のクラスから[〜#〜] x [〜#〜]メソッドを呼び出すことが非常に期待されています。これらの[〜#〜] x [〜#〜]メソッドをテストしていないため、実行する必要があるのは です。 mock これらのメソッド。

私はあなたが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メソッドのテストに役立つことを願っています。

18
Jalayn