是否需要 Spring/Micronaut 存储库测试
Are Spring/Micronaut repository tests necessary
你好 Whosebug 社区。
我在工作中争论是否完全有必要对 spring-data JPA(或 Micronaut 版本)进行存储库测试。
这将是我的应用程序设置:
@Controller
➡ @Service
/@Sigleton
➡ Repository<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 的测试要快得多。所以(再次主观)我的个人规则是:如果你可以通过单元测试获得对代码的信心 - 那就去做吧。如果您需要检查集成 - 请进行集成测试。
你好 Whosebug 社区。
我在工作中争论是否完全有必要对 spring-data JPA(或 Micronaut 版本)进行存储库测试。
这将是我的应用程序设置:
@Controller
➡ @Service
/@Sigleton
➡ Repository<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 的测试要快得多。所以(再次主观)我的个人规则是:如果你可以通过单元测试获得对代码的信心 - 那就去做吧。如果您需要检查集成 - 请进行集成测试。