SpringBoot App中的Mockito Mock和间谍

时间:2017-02-22 14:57:30

标签: java unit-testing spring-boot junit mockito

我已经阅读了不少文章/博客/ StackOverflow问题,但关于Mockito模拟和间谍的困惑仍然存在。所以,我开始尝试在一个小Spring Boot应用中实现它们。我的应用有ProductRepositoryCrudRepository

目前我正在通过模拟ProductRepository来测试存储库,如下所示

  @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()));
     }
   }

测试通过。这是正确的方法吗?我还想了解如何在这里使用@Spy以及为什么需要它?任何与此相关的特定场景都是最受欢迎的。

提前致谢。

1 个答案:

答案 0 :(得分:2)

我已经看了你的测试,并且有一些事情要记住(这是基于我的经验,所以最后的电话由你决定):

1)Hamcrest - 如果可能的话,我强烈建议您使用Hamcrest进行断言实现。      首先,它比标准的junit断言更通用,功能更丰富。      其次,你可能有一天需要(就像我在其中一个项目中所做的那样)从junit切换到testng进行检查。      将所有断言都基于xunit-neutral实现,交换机不会那么痛苦。

2)断言 - 而不是assertNullassertEquals代替hamcrest的assertThat(String description, T value, Mathcer<T> matcher);    因此,当测试中断时,您将收到明确的错误消息。

3)小测试 - 在您的存储库测试中..不要将所有案例都放在一个测试中。    尝试为以下情况创建许多小而简单的测试:findOne .. count .. findAll等。    再次,当这样的小测试中断时,更容易找到问题。    如果有更多的案例,你将不会得到200多行测试用例,这是不可接受的

4)命名 - 不要将测试命名为.. testXYZ。    很明显,这些是测试方法。    我建议使用BDD命名方式:shouldX_whenY_givenZ。    F.E. shouldReturnZeroCount_givenNoEntitiesInTheDatabase

5)结构 - 尝试将每个测试实现拆分为三个显式部分,包括最佳结果的注释:

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

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

         // Act

            // classUnderTest.process()

         // Assert

           // assertThat(..)
   }

6)不要在Mock / Spy测试之间拆分测试类。有一个ImplTest。

7)永远不要模拟您正在测试的课程。在最坏的情况下,如果你必须模拟被测试类的一些方法,请使用Spy。    模拟的目的是隔离被测试类中的实现,以便在测试期间仅调用类逻辑。    模拟只有类的依赖。