2017-02-22 3 views
1

私はかなりの記事/ブログ/ StackOverflowの質問を読んだが、Mockitoモックとスパイに関する混乱は依然として残っている。そこで、私は小さなSpring Bootアプリで実装しようと試みました。私のアプリのProductRepositoryCrudRepositoryです。SpringBoot App内のMockitoモックとスパイ

@RunWith(SpringRunner.class) 
    @SpringBootTest(classes = {RepositoryConfiguration.class}) 
    public class ProductRepositoryMockTest { 

    @Mock 
    private ProductRepository productRepository; 
    @Mock 
    private Product product; 

    @Test 
    public void testMockCreation(){ 
     assertNotNull(product); 
     assertNotNull(productRepository); 
    } 

    @Test 
    public void testSaveProduct() { 
     assertThat(product.getId(), is(equalTo(0))); 
     when(productRepository.save(product)).thenReturn(product); 
     productRepository.save(product); 
     //Obviously this will fail as product is not saved to db and hence 
     //@GeneratedValue won't come to play 
     //assertThat(product.getId() , is(not(0))); 
    } 

    @Test 
    public void testFindProductById() { 

     when(productRepository.findOne(product.getId())).thenReturn(product); 
     assertNotNull(productRepository.findOne(product.getId())); 
     assertEquals(product, productRepository.findOne(product.getId())); 
    } 
    } 

テストパスを次のように

現在、私はProductRepositoryをあざけることにより、リポジトリをテストしています。これは正しい方法ですか?私はまたここで@Spyの使い方を理解したいのですが、なぜそれが必要なのでしょうか?これに関する特定のシナリオは、大歓迎です。

ありがとうございます。

+1

あなたのリポジトリをテストしないでください。ユニットテストに関するサービスレイヤに焦点を当ててください。あなたがあなたのリポジトリの中にいくつかのロジックを持っているなら、それは恐らく設計の欠陥です。 –

+0

ええ、ポイントを得ました。ありがとう。 – user2693135

+0

@Maciej Kowalski最後に、あなたの入力に基づいてモックとスパイを使用してサービス層をテストしました。しかし、私がそれを正しく行ったかどうかわからない、私のレポはhttps://github.com/ximanta/mockito_spy_exampleです。あなたの観察は貴重です。必要に応じて、これを質問として投稿できます。ありがとう。 – user2693135

答えて

2

私はあなたのテストを見て撮影してきたし、心に留めておくべきいくつかのこと(最後の呼び出しはあなた次第ですので、これは私の経験に基づいています)があります。

1)Hamcrestが - その場合はあなたのアサーションの実装にHamcrestを使用することを強くお勧めします。 まず、標準junitアサーションよりもはるかに多用途で機能豊富です。 第二に、junitからexamleのためのtestngに切り替える必要があるのはいつか(私のプロジェクトの1つとして) xunit-neutralの実装に基づいてすべてのアサーションを作成しても、スイッチはそれほど苦痛ではありません。

2)アサーション - 代わりのassertNullassertEqualsときの試験休憩あなたは明確なエラーメッセージを取得することにhamcrestのassertThat(String description, T value, Mathcer<T> matcher); 感謝のために行きます。

3)小テスト - リポジトリテストでは、すべてのケースを1つのテストに入れないでください。 findOne .. count .. findAllなどのような場合には、小さくて簡単なテストをたくさん作成してみてください。 このような小さなテストを実行すると、問題を見つけるのが簡単になります。 そして、より多くのケースでは、あなたが文句を言わない命名)

4受け入れられないテストケースの200以上の行で終わる来る場合 - .. testXYZとしてあなたのテストに名前を付けないでください。 これはテストメソッドであることは明らかです。 BDDの名前付け方法を使用することをお勧めします。shouldX_whenY_givenZ F.e. shouldReturnZeroCount_givenNoEntitiesInTheDatabase

5)構造 - 最良の結果についてのコメントを含め、3つの明示的なセクションであなたのテスト実装のそれぞれを分割するようにしてください:

public void should..() throws Exception{ 
     // Arrange 

      // when().then() 
      // mock() 

     // Act 

      // classUnderTest.process() 

     // Assert 

      // assertThat(..) 
    } 

6)はモックの間あなたのテストクラスを分割しないでください/スパイテスト。 ImplTestが1つあります。

7)あなたがテストしているクラスをモックしないでください。ワーストケースのシナリオでは、テスト対象のクラスのメソッドのいくつかを模擬しなければならない場合は、Spyを使用します。 mockingのポイントは、テスト中にそのクラスロジックのみが呼び出されるように、テスト対象クラス内の実装を分離することです。 クラスの依存関係のみをモックします。

+0

ありがとう。物事は今明らかです。 – user2693135

+0

コンストラクタ/セッターメソッドを使ってモックを使ってテスト中のオブジェクトを初期化するのと比べて、InjectMockアノテーションを使用しないのはなぜですか? – user2693135

+0

は実際に奨励されています。テストコードを明確にする –

関連する問題