【问题标题】:IllegalArgumentException: No visible constructors in class TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBeanIllegalArgumentException:TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean 类中没有可见的构造函数
【发布时间】:2018-05-11 07:55:43
【问题描述】:

我正在尝试使用 h2 数据库为 Spring Boot JPA 应用程序编写集成测试。不知何故,没有创建 TestEntityManager。我尝试在论坛上寻求帮助,但找不到任何相关信息。

感谢任何人可以提供帮助或提供一些指导。

谢谢。

我的代码如下:

存储库:

@Repository
public interface ConfigRepository extends JpaRepository<Config, Long> {

    Config findByKey(ConfigKey configKey);

}

配置:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "testEntityManagerFactory",
    transactionManagerRef = "testTransactionManager",
    basePackages = "com.abc.xyz.business.repository")
public class TestPersistenceConfig {

private static final String TEST_PERSISTENCE_UNIT = "emTestPersistenceUnit";

@Bean(name = "testEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource());
    entityManagerFactoryBean.setPackagesToScan(new String[] { "nl.rabobank.rom.exception.manager.rom.em.business.domain" });
    entityManagerFactoryBean.setPersistenceUnitName(TEST_PERSISTENCE_UNIT);

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactoryBean.setJpaProperties(additionalProperties());

    return entityManagerFactoryBean;
}

@Bean
@Profile("test")
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.h2.Driver");
    dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1");
    dataSource.setUsername("sa");
    dataSource.setPassword("sa");

    return dataSource;
}

@Bean(name = "testTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    return transactionManager;
}

private Properties additionalProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty("em.hibernate.hbm2ddl.auto", "none");
    hibernateProperties.setProperty("hibernate.show_sql", "true");
    hibernateProperties.setProperty("hibernate.format_sql", "true");
    hibernateProperties.setProperty("em.hibernate.naming.physical-strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
    hibernateProperties.setProperty("em.properties.hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
    return hibernateProperties;
}

}

测试:

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("test")
@ContextConfiguration(classes = {TestPersistenceConfig.class})
public class ConfigRepositoryTest {

    @Autowired
    private TestEntityManager entityManagerFactory;

    @Autowired
    private ConfigRepository configRepository;

    @Test
    public void test1() {
        Config config = 
    configRepository.findByKey(ConfigKey.PURGE_DATE_RETENTION_CALENDAR_TYPE);
        assertNotNull(config);
    }
}

POM.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- To run tests on IDE such as Eclipse, Intellij -->
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-runner</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4-common</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc7</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

堆栈跟踪:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TestExceptionHandlerEntityManagerFactory' defined in nl.rabobank.rom.exception.manager.rom.em.business.TestPersistenceConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
...
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'entityManagerFactory' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
    ... 42 more
Caused by: java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
    at org.springframework.cglib.proxy.Enhancer.filterConstructors(Enhancer.java:666)
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:567)

【问题讨论】:

  • 您使用的是 Spring Boot,那么您为什么要绕开它呢?放弃你的 TestPersistenceConfig 并在你的 src/test/resources 中创建一个 application.properties 并让 Spring Boot 完成繁重的工作。
  • 最初我尝试了这种方法,但由于某种原因它不起作用,因此采用了这种方法。但是在您的建议和一些更改之后,例如在配置类中使用 @EnableJpaRepositories(basePackages = "....") 和 @EntityScan(basePackages = "....") 等注释,它可以工作。谢谢@M。拒绝你的方向。
  • 你需要 @EnableJpaRepositories@EntityScan 的事实基本上告诉我你没有遵循将 @SpringBootApplication 注释类放在顶级包中的一般建议,这基本上禁用了很多的自动功能(如 Spring Data JPA 检测等)。
  • @M. Deinum,我有一个多模块 spring-boot 应用程序(例如:业务、服务等),其中我有一个模块,其类用“@SpringBootApplication”注释。该模块具有在其 POM 中定义的其余模块的依赖关系。在这种情况下,是否仍然可以将“@SpringBootApplication”注释类放在顶层?
  • 为什么不呢。一切都在同一个类路径中。

标签: java spring-boot spring-data-jpa integration-testing


【解决方案1】:

如果您在测试中有生产类型数据库,则必须将 @AutoConfigureTestDatabase(replace=Replace.NONE) 添加到测试类。

只需将上述注释添加到 ConfigRepositoryTest 类即可解决您的问题。

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("test")
@ContextConfiguration(classes = {TestPersistenceConfig.class})
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class ConfigRepositoryTest {
  ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    相关资源
    最近更新 更多