是否需要 Spring/Micronaut 存储库测试

Are Spring/Micronaut repository tests necessary

你好 Whosebug 社区。

我在工作中争论是否完全有必要对 spring-data JPA(或 Micronaut 版本)进行存储库测试。

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

@Controller@Service/@SigletonRepository<Entity>

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

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

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

然而,我通常在项目中看到的是 Repository 被模拟掉了。 为了测试自定义存储库调用,有单独的测试来确保存储库功能按预期工作。

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

如果您没有在服务 junits 中模拟您的 Repository,那么它是一个集成测试而不是单元测试。如果你想保持这种状态也没关系。

但是如果你想编写单元测试来测试你的各个层,那么你应该模拟你的 Repository 并为 Repository 编写单独的集成测试。

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

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

现在 Spring 中有 @DataJpaTest@WebMvcTest 等注释。他们创建了一个 "slice" 的应用程序上下文,仅加载必要的 bean,并模拟/忽略其他 bean。例如,在 @WebMvcTest 中根本没有加载 JPA 存储库。

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

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

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

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

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

更新

根据 OP 的评论:

lot of the 'mysql query' is already been taken care of by the framework, so why should I explicitly test the repository

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

Is it worth it to write Unit tests for services?

好吧,这取决于服务的实际作用。 如果他们 运行 一个复杂的算法,无法通过集成测试轻松检查(比如服务在各种情况下需要各种模拟),那么可以完成服务的单元测试。

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