Justin
Justin

Reputation: 1249

Spring boot test wrong configuration classes

I am trying to test my repository layer using Spring Boot 2.0.1 but when I run my test class, Spring tries to instantiate a Config class not from the test package.

Here is the test code:

TestConfig.class

@Configuration
@Import(value = {TestDatabaseConfig.class})
@Profile("local")
public class TestConfig {

}

TestDatabaseConfig.class

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "logEntityManagerFactory",
        transactionManagerRef = "logTransactionManager",
        basePackages = { "it.xxx.yyy.repository.log" })
@EntityScan(basePackages = {"it.xxx.yyy.model.log", "it.xxx.yyy.common"})
@Profile("local")
public class TestDatabaseConfig {

@Bean("logDataSourceProperties")
public DataSourceProperties logDataSourceProperties() {
    return new DataSourceProperties();
}


@Bean(name = "logDataSource")
public DataSource dataSource(@Qualifier("logDataSourceProperties") DataSourceProperties properties) {
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("classpath:schema.sql")
            .build();
}

@Bean(name = "logEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean logEntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                      @Qualifier("logDataSource") DataSource logDataSource) {
    return builder.dataSource(logDataSource)
            .packages("it.xxx.model.log")
            .persistenceUnit("log")
            .build();
}

@Bean(name = "logTransactionManager")
public PlatformTransactionManager logTransactionManager(@Qualifier("logEntityManagerFactory")EntityManagerFactory logEntityManagerFactory) {
    return new JpaTransactionManager(logEntityManagerFactory);
}

}

When I run this class

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("local")
public class LogRepositoryTest {

    @Autowired
    private ResultLogRepository resultLogRepository;

    @Test
    public void init(){
    }
}

it says :

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kafkaProducer': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'kafka.topic.operation' in value "${kafka.topic.operation}"
[...]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'kafka.topic.operation' in value "${kafka.topic.operation}"

But I cannot understand why it brings up my KafkaProducer.class from my main package (that has @Configuration annotation on it).

Upvotes: 1

Views: 3144

Answers (1)

pleft
pleft

Reputation: 7915

In your LogRepositoryTest test class you should indicate the alternate test configuration class that should be taken into account, in your case I think should be the TestConfig.

From Spring Boot documentation:

If you are familiar with the Spring Test Framework, you may be used to using @ContextConfiguration(classes=…​) in order to specify which Spring @Configuration to load. Alternatively, you might have often used nested @Configuration classes within your test.

So annotate LogRepositoryTest with @ContextConfiguration(classes = {TestConfig.class})

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("local")
@ContextConfiguration(classes = {TestConfig.class})
public class LogRepositoryTest {

    @Autowired
    private ResultLogRepository resultLogRepository;

    @Test
    public void init(){
    }
}

UPDATE

Also annotate your configuration class with:

@EnableAutoConfiguration

Something like:

@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "logEntityManagerFactory",
        transactionManagerRef = "logTransactionManager",
        basePackages = { "it.xxx.yyy.repository.log" })
@EntityScan(basePackages = {"it.xxx.yyy.model.log", "it.xxx.yyy.common"})
@Profile("local")
public class TestDatabaseConfig {
//...
}

UPDATE 2

For error:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' available: expected single matching bean but found 2: logDataSourceProperties,spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties

Completely remove the method:

@Bean("logDataSourceProperties")
public DataSourceProperties logDataSourceProperties() {
    return new DataSourceProperties();
}

and change your:

@Bean(name = "logDataSource")
public DataSource dataSource(@Qualifier("logDataSourceProperties") DataSourceProperties properties) {
 // ...
}

to:

@Bean(name = "logDataSource")
public DataSource dataSource(DataSourceProperties properties) {
 // ...
}

Upvotes: 1

Related Questions