3

In a SpringBoot (2.2.1,2.2.2) application a sliced @DataJpaTest doesn't run because a bean holding @ConfigurationProperties could not be created.

The test:

@DataJpaTest
public class FooCustomerServiceTest
{
    @Autowired
    FooCustomerRepository repo;

    @Test
    void findAll()
    {
       repo.findAll();
    }
}

When I try to run the test I get a

No qualifying bean of type 'foo.appconfig.AppInfoConfig' available

foo.appconfig.AppInfoConfig

@ConfigurationProperties(prefix = "app.info")
public class AppInfoConfig
{
    private String name;

    ...
}

It is referenced by one @Component not related to the test.

The foo.Application that is used has no special annotations

@SpringBootApplication
@ComponentScan
@ConfigurationPropertiesScan
public class Application
{
    public static void main( final String[] args )
    {
        SpringApplication.run( Application.class, args );
    }
}

As sliced tests only scan for certain components (@Entity and @Repository in case of @DataJpaTest) 'AppInfoConfig' is not scanned. That's ok but why is it tried to be injected to another controller that is neither a entity nor a repository?

How can I enable the correct creation of AppInfoConfig or disable the creation at all?

NB: A @TestConfigurationhaving a @Bean method does work but is not really handy if you have a lot of those @ConfigurationProperties classes.

Alex
  • 115
  • 1
  • 9

2 Answers2

8

Why do you have @ComponentScan on your SpringBootApplication? Doing so overrides the configuration that is applied on it, including the filter that customizes classpath scanning in slice tests.

See the documentation for more details.

Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89
0

I'm sharing what I experienced.

My problem is exactly the same as the OP explained and moreover the cause of the problem is also the same as the accepted answer.

But in my case, The @ComponentScan is required because the application needs to scan components outside the application package.

@ComponentScan(
        basePackageClasses = {
                Application.class, // this application
                some.other.NoOp.class // resides in a dependency
        }
)
@SpringBootApplication
class MyApplication {
}

I spent several hours what's wrong with my @DataJpaTest even peeped this thread.

My solution is using a custom context replacing the main application.

@EnableAutoConfiguration
@SpringBootConfiguration
@Slf4j
class MyDataJpaTestConfiguration {

}

And imports it from the @DataJpaTest class.

@Import(MyDataJpaTestConfiguration.class)
@DataJpaTest
abstract class MyEntityDataJpaTest {
}
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184