防止在 JUnit 中执行 jpa @Query

Posted

技术标签:

【中文标题】防止在 JUnit 中执行 jpa @Query【英文标题】:Prevent executing jpa @Query in JUnit 【发布时间】:2021-02-03 16:17:42 【问题描述】:

我有一个 Spring Boot 项目(版本 2.3.1.RELEASE),我正在尝试编写不使用数据库的 JUnit 测试(全部模拟)。

为此我配置了一个junit环境H2作为数据库

spring.datasource.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.url=jdbc:h2:mem:db;TRACE_LEVEL_FIlE=4
spring.datasource.username=sa
spring.datasource.password=

有了这个非常常规的存储库

public interface AccountRepository extends JpaRepository<Account, Long> 

@Query("SELECT A FROM Account A WHERE "
            + "A.state='PENDING' AND "
            + "P.origin='WS' AND "
            + "UPPER(P.type)='R'")
    public List<Account> pending();

我的测试控制器以

开头
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = LoadBranchesController.class)
@ComponentScan(basePackages =  Constant.ROOT_PACKAGE )
@TestPropertySource(locations = "classpath:application-junit.properties")
class LoadBranchesControllerTest 

当我在 junit 测试中运行 ControllerTests 时,我的问题就出现了。在引导时,它会抱怨:

2020-10-20 20:37:38 WARN  -  WARN - org.hibernate.engine.jdbc.spi.SqlExceptionHelper -  SQL Error: 42102, SQLState: 42S02
2020-10-20 20:37:38 ERROR - ERROR - org.hibernate.engine.jdbc.spi.SqlExceptionHelper -  Table "AP_ACCOUNTS" not found; SQL statement:

这是因为他试图检查这个查询。但是 H2 是空的(我想要的方式)。

有没有办法在引导时禁用 JpaRepositories 的查询执行?

【问题讨论】:

【参考方案1】:

解决方案有两条腿,应用于每个测试类:

    在 ComponentScan 中,必须排除存储库
    @ComponentScan(Constant.ROOT_PACKAGE + ".helper")

所以,所有带有@Query 的 Bean,必须在所有扫描的组件之外

    组件在任何时候自动装配存储库,必须模拟,即使它们没有被使用
    @MockBean
    private AccountRepository accountRepositoryMock;

【讨论】:

以上是关于防止在 JUnit 中执行 jpa @Query的主要内容,如果未能解决你的问题,请参考以下文章

Spring JPA Repository findAll 在 JUnit 测试中不返回任何数据

防止 Application / CommandLineRunner 类在 JUnit 测试期间执行

Spring Boot JPA:@Modifying @Query 没有效果

为啥 JPA 提交在应用程序中失败,但在 JUnit 中有效?

Spring Data JPA 中使用Update Query更新实体类问题

jpa中@Query的nativeQuery属性的作用