You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JPA集成测试:TestEntityManager创建失败及构造器异常

解决TestEntityManager创建失败及TestDatabaseAutoConfiguration构造器异常问题

我帮你梳理下问题根源和解决办法,你遇到的异常本质是自动配置与自定义配置的冲突导致的,下面一步步来解决:

核心原因分析

@DataJpaTest是Spring Boot提供的切片测试注解,它会自动帮你配置嵌入式数据库、JPA组件(包括TestEntityManager)。但当你通过@ContextConfiguration手动指定自定义的TestPersistenceConfig时,自动配置的TestDatabaseAutoConfiguration会和你的自定义数据源配置冲突——这个自动配置类里的EmbeddedDataSourceFactoryBean是私有内部类,冲突场景下Spring尝试实例化它时就会抛出"无可见构造器"的异常。

解决方案步骤

1. 调整测试类注解,消除配置冲突

既然你已经自定义了完整的JPA持久化配置,就不需要依赖@DataJpaTest的自动配置了。修改测试类如下:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {TestPersistenceConfig.class})
@Transactional // 保持测试事务性,测试结束自动回滚数据
public class ConfigRepositoryTest {

    @Autowired
    private EntityManager entityManager; // 用标准EntityManager代替TestEntityManager

    @Autowired
    private ConfigRepository configRepository;

    @Test
    public void test1() {
        // 如果需要TestEntityManager的封装功能,可以手动实例化:
        // TestEntityManager testEntityManager = new TestEntityManager(entityManager);
        
        Config config = configRepository.findByKey(ConfigKey.PURGE_DATE_RETENTION_CALENDAR_TYPE);
        assertNotNull(config);
    }
}

如果一定要用TestEntityManager,直接通过注入的标准EntityManager手动实例化即可,它本质是对标准EntityManager的封装。

2. 修正JPA配置的属性前缀错误

你的TestPersistenceConfig里的Hibernate属性多了无效的em.前缀,这会导致Hibernate无法识别这些配置,同时测试用H2数据库却配置了Oracle方言,容易引发SQL兼容问题,修正如下:

private Properties additionalProperties() {
    Properties hibernateProperties = new Properties();
    // 去掉无效的em.前缀
    hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "none");
    hibernateProperties.setProperty("hibernate.show_sql", "true");
    hibernateProperties.setProperty("hibernate.format_sql", "true");
    hibernateProperties.setProperty("hibernate.naming.physical-strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
    // 测试用H2数据库,改用H2方言
    hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
    return hibernateProperties;
}

3. 简化Maven依赖,避免版本冲突

spring-boot-starter-test已经包含了JUnit 5、Mockito等核心测试依赖,不需要重复引入;同时建议用spring-boot-starter-data-jpa代替单独的Hibernate依赖,Spring Boot会帮你管理版本兼容性:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- 补充PowerMock的JUnit4模块依赖 -->
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

备选方案:保留@DataJpaTest的同时使用自定义配置

如果你想保留@DataJpaTest的切片测试特性,可以通过注解禁用自动配置的嵌入式数据库,这样就能兼容你的自定义数据源:

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("test")
@ContextConfiguration(classes = {TestPersistenceConfig.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class ConfigRepositoryTest {
    // 你的测试代码
}

内容的提问来源于stack exchange,提问作者horizon7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:20:55