-2

你好 stackoverflow 社区。

关于 spring-data JPA(或 Micronaut 版本)的存储库测试是否有必要,我在工作中有一个争论。

这将是我的应用程序设置:

@Controller@Service/ @SigletonRepository<Entity>

在我的服务测试中,我会使用@ExtendWith(SpringExtension::class)扩展名(Junit5)

在创建测试设置时,我会@MockBean放弃我需要调用的其他系统(如 REST-API),但@AutowireRepository的 . 在设置我的测试数据时,我只需使用注入的存储库将所需的实体保存到H2内存数据库中。

这也将测试我的数据库逻辑和业务逻辑。在 100% 测试覆盖率的情况下,我已经测试了生产中可能发生的所有数据库调用。

但是我通常在项目中看到的Repository是被嘲笑了。要测试自定义存储库调用,有单独的测试以确保存储库功能按预期工作。

您对此有何评论。你更喜欢没有存储库模拟的方法还是有,为什么?

4

2 回答 2

1

我没有使用 Micronaut 的经验,但我相信我的回答将适用于这两个框架:

例如,spring 支持不同类型的集成测试。基本上,您在测试中运行 spring 上下文这一事实已经意味着它不仅仅是一个单元测试。一般来说,Spring 测试包用于集成测试。

现在在 Spring 中有诸如@DataJpaTest,之类的注释@WebMvcTest。他们创建应用程序上下文的“切片”,仅加载必要的 bean,并模拟/省略其他。例如,在@WebMvcTestJPA 存储库中根本没有加载。

您也可以创建自己的切片。

现在,如果您想检查您的休息层(正确定义了控制器,以正确的方式验证请求,根据请求,您将获得正确格式的响应等等),您可以使用@WebMvcTest.

如果您想测试 sql 查询是否正确 - 您可以使用@DataJpaTest(当然假设您使用 JPA / Spring Data)。

现在,如果您想测试服务逻辑,有时您甚至不需要集成测试(加载 spring 上下文),因为您可以对服务运行单元测试并模拟存储库调用或对外部服务的调用(如果有的话)。

关于H2方法。虽然人们使用它来测试他们的 DB 层(SQL 查询),但有时它的工作方式与生产中的数据库并不完全相同。这意味着有时您无法在测试中真正运行相同的 SQL 查询。对于这些情况,我推荐 TestContainers 项目:在测试启动时运行数据库的 Docker 映像,并在测试结束后停止映像。

更新

根据OP的评论:

框架已经处理了很多“mysql查询”,所以我为什么要显式测试存储库

这是主观的,但让我这样说:测试首先是让开发人员对代码有信心的工具。如果开发人员想要确保查询的行为符合预期,那么测试是一个可以提供帮助的工具。特别是关于查询:也许查询是错误的,也许它是一个本机查询,无论如何都应该检查。也许有许多查询一个接一个地运行。仅由您决定。

为服务编写单元测试是否值得?

嗯,这取决于服务实际上做了什么。如果他们运行的复杂算法无法通过集成测试轻松检查(例如服务在各种情况下需要各种模拟),那么可以对服务进行单元测试。

此外,一般来说,单元测试比 Spring 的测试要快得多。所以(又是主观的)我个人的规则是:如果你能通过单元测试获得对代码的信心——那就去做吧。如果您需要检查集成 - 进行集成测试。

于 2020-02-20T05:12:10.383 回答
0

如果您没有嘲笑您Repository的服务中的junit,那么它是一个集成测试而不是一个单元测试。如果你想保持这种方式也很好。

但是,如果您想编写单元测试来测试您的各个层,那么您应该模拟您的Repository并为Repository.

于 2020-02-20T04:14:03.817 回答