测试 Spring 引导应用程序的最佳方法是什么?通过服务器参与或通过创建模拟环境?

What is the best way to test Spring Boot application? With server involvement or by creating mock environment?

我想测试我的 Spring 启动应用程序的层 - 服务、数据、控制器。

我知道 Spring Boot 我们可以在服务器参与或不参与(通过创建模拟环境)的情况下测试这些。所以我的问题是——测试这些层的最佳实践是什么?或者是否取决于我们要测试的特定层?

单元测试很简单。您坚持 SRP 原则,模拟所有协作者并单独测试。

说到集成测试,没有明确的答案和确定的标准。它总是取决于您正在从事的项目,甚至是具体的功能。

在使用了一些 Spring 引导应用程序之后,我倾向于将您的 IT 套件分成四个 parts/categories:

1) REST API 测试

所以我们只测试 @Restontrollers。您使用 @WebMvcTest(MyController.class)@WebFluxTest(MyController.class) 取决于您使用的控制器类型。从服务层向下的任何东西都被模拟了。您尽可能多地强调输入 params/request body 并测试每个组合。

2) 存储库测试

仅验证 ORM 层的测试。为此,您使用 @DataJpaTest。在这里,您可以为您拥有的每个存储库方法测试每个可能的场景,而不关心调用它的是什么等。

3) 切片测试

这是您验证 @Component@Service bean 之间交互的地方。这是测试应用程序实际业务逻辑的地方。由您决定是通过 REST 发送数据还是使用对 top-most @Service 的调用。尽管在这种情况下,我总是存根 @Repository 层。

4) 端到端测试

这些在真实的 Web 服务器上工作:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

这里没有嘲笑。

讨论

这里的关键是决定每一个应该使用多少,记住切片测试可能是最重要的。

主要重点肯定不应该放在端到端测试上。它们有点像句子末尾的逗号。它们最慢并且需要最多 set-up。因此,它们最 error-prone,难以维护且难以理解。理想情况下,这些应保持在最低限度(仅涵盖最关键的情况)。

此外,当 运行 您的 IT 套件应按以下顺序分组:

1) 控制器测试

2) 切片测试

3) 存储库测试

4) E2E 测试

(从最快和需要最少环境交互到最慢)。

同样,由团队决定我们要使用其中的哪些,以什么顺序和频率。

补充阅读: 我写了一篇关于 common integration testing mistakes 的文章,它可以补充上面给出的信息,并帮助您在项目中走得更远。