Spring 提供 JpaRepositories 的存根实现吗?

问题描述 投票:0回答:3

我正在尝试对我的服务类进行单元测试,看起来与此类似:

   @Service
   public class SomeQueryService {

    private final SomeRepository repository;

    public SomeQueryService(SomeRepository repository) {
        this.repository = repository;
    }

    public void doSomething() {
        // code doing some magic
    }
}

SomeRepository
是扩展
JpaRepository
接口的简单存储库接口。

我想做的是对这个服务进行单元测试,以验证它是否正常工作。

我不想使用mockito来模拟存储库行为,我想要一些内存中的实现(在列表或地图上)来模仿数据库行为。

Spring提供这样的假实现吗?

我想避免自己对此类存储库进行存根实现,因为我将在许多其他地方使用此类测试。

java spring unit-testing spring-data-jpa
3个回答
1
投票

RealLifeDeveloper 创建了一个 MIT 许可的帮助程序类来完成您想要的操作:使用仅包装 Collection 的普通旧 java 对象实现存储库接口,并将其称为“InMemoryJpaRepository”。您仍然需要自己实现一些逻辑1,尽管如果您的查询不太复杂,这应该很容易。

一篇文章解释了如何通过示例执行此操作:https://reallifedeveloper.com/creating-in-memory-versions-of-spring-data-jpa-repositories-for-testing/

存储库(也包括其他内容)位于 github 上:https://github.com/reallifedeveloper/rld-build-tool

用于创建内存数据库的特定帮助程序文件位于 https://github.com/reallifedeveloper/rld-build-tools/tree/master/src/main/java/com/reallifedeveloper/tools/test/数据库/内存如果您不想要整个存储库。

1 “不要在测试中放入逻辑”规则的存在是有原因的,并且在这里显然被违反了。然而,其他答案提到的众所周知且广泛使用的替代方案,H2 测试和广泛的模拟,也有其缺点。


编辑:我保留这个答案,因为它是正确的,但我不会再推荐这个。 请注意,您的测试不会有 hibernate/jpa 上下文,因此不会存在与持久性相关的代码的相当多的复杂性:刷新、ID 生成、LazyInitializationExceptions、事务(回滚?)、sql 与 jpql 缓存问题。将 spring-data JPA 存储库视为“集合”是一种有缺陷的理解,或者至少是对正在发生的事情的一个不够复杂的模型。

模拟适用于简单的情况,您确定上述问题不存在。对于复杂的情况,您需要 hibernate/jpa-context,因为 spring-data 不会将其抽象出来,因此选择类似 H2 数据库或 Testcontainers 的内容作为

@DataJpaTest
。是的,测试会运行得更慢并且需要更长的时间来设置。


0
投票

您所指的测试类型称为“集成测试”或“端到端测试”,因为与仅测试一种方法的单元测试相比,它测试整个应用程序或其中的很大一部分。

https://www.guru99.com/unit-test-vs-integration-test.html

您不应该对您的存储库进行单元测试,因为它们已经经过 Spring 团队的充分测试。

解决方案:

您可以创建一个使用 Spring Boot 启动整个 Spring 容器的测试:

只需在测试文件夹中创建一个类并用以下注释:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTestClass {

  @Test
     public void test() {
  }

}

然后,您可以使用 H2 配置嵌入式数据库,以便您的测试不使用生产数据库,只需遵循 Spring Boot 数据库初始化文档即可。

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

PS。您还可以在测试类上使用以下注释创建特定的配置文件:

@ActiveProfiles("test")


0
投票

Spring Data 不提供该接口的虚假实现。

您必须自己创建它或使用 Mockito 等模拟框架。

© www.soinside.com 2019 - 2024. All rights reserved.