In a SpringBoot application, I would like to do some test about the repository layer.
@RunWith(SpringRunner.class)
@DataJpaTest
public class VisitRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private VisitRepository visitRepository;
...
}
When I try to run test from VisitRepositoryTest
, I get an error about DefaultConfigService
Field defaultConfigService in com.norc.Application required a bean of type 'com.norc.service.DefaultConfigService' that could not be found.
So this needs to run the Application
?
I tried to put a bean of DefaultConfigService
in VisitRepositoryTest
, but it's not allowed.
This class is used in my app
@EntityScan(basePackageClasses = {Application.class, Jsr310JpaConverters.class})
@SpringBootApplication
@EnableScheduling
public class Application implements SchedulingConfigurer {
@Autowired
private DefaultConfigService defaultConfigService;
...
}
How to manage that?
In my Application, I use this class in a cron tab:
@Service
public class DefaultConfigServiceImpl implements DefaultConfigService {
private final DefaultConfigRepository defaultConfigRepository;
@Autowired
public DefaultConfigServiceImpl(final DefaultConfigRepository defaultConfigRepository) {
this.defaultConfigRepository = defaultConfigRepository;
}
}
The problem is that your @SpringBootApplication
has some additional configuration regarding scheduling and by adding that there and not having a custom @SpringBootConfiguration
for your test, such scheduling requirement becomes mandatory for everything.
Let's take a step back. When you add @DataJpaTest
, Spring Boot needs to know how to bootstrap your application context. It needs to find your entities and your repositories. Slice tests will recursively search for a @SpringBootConfiguration
: first in the package of your actual test, then the parent, then the parent and if it doesn't find one it will throw an exception.
@SpringBootApplication
is a @SpringBootConfiguration
so if you don't do anything special, slice tests will use your app as the source for configuration (which is IMO, an excellent default).
Slice tests do not blindly start you app (otherwise that wouldn't be slicing) so what we do is disable auto-configuration and customize component scan for the task at hand (only scanning entities and repositories and ignoring all the rest when you use @DataJpaTest
). That's a problem for you since the application configuration is applied and the scheduling stuff should be available. But dependent beans aren't scanned.
In your case, if you want to use slicing the scheduling configuration should move to a SchedulingConfiguration
or something (it won't be scanned with slicing as explained above). Regardless, I think it's cleaner to separate a SchedulingConfigurer
implementation anyway. If you do that, you'll notice the error will go away.
Let's assume now that you want for that particular test that FooService
is also available. Rather than enabling component scan as dimitrisli suggested (that's basically disabling slicing for your configuration), you can just import the missing class
@RunWith(SpringRunner.class)
@DataJpaTest
@Import(FooService.class)
public class VisitRepositoryTest {
...
}