我已经阅读了很多文章/博客/StackOverflow 问题,但是关于 Mockito 模拟和 spy 的困惑仍然存在。所以,我开始尝试在一个小的 Spring Boot
中实现它们。应用程序。我的应用程序有一个 ProductRepository
延长 CrudRepository
.
目前我正在通过模拟 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) Hamcrest - 如果可能的话,我强烈建议您将 Hamcrest 用于您的断言实现。
首先,它比标准的 junit 断言更加通用和功能丰富。
其次,你可能有一天需要(就像我在我的一个项目中所做的那样)例如从 junit 切换到 testng。
拥有基于 xunit 中性实现的所有断言,切换不会那么痛苦。
2) 断言 - 而不是 assertNull
, assertEquals
去hamcrest的assertThat(String description, T value, Mathcer<T> matcher);
多亏了这一点,您将在测试中断时收到清晰的错误消息。
3)小测试 - 在您的存储库测试中......不要将所有案例都放在一个测试中。
尝试为以下情况创建许多小而简单的测试:findOne..count..findAll 等。
同样,当像这样的小测试中断时,会更容易找到问题。
如果会有更多的案例出现,您最终不会得到 200 多行测试用例,这是 Not Acceptable
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) 永远不要 mock 您正在测试的类(class)。在最坏的情况下,如果您必须模拟被测类的某些方法,请使用 Spy。
模拟的重点是隔离被测类中的实现,以便在测试期间只调用类逻辑。
仅模拟类的依赖项。
关于java - Spring Boot 应用程序中的 Mockito 模拟和 spy ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42394958/