Skip to content
Advertisement

Why component scanning does not work for Spring Boot unit tests?

The service class FooServiceImpl is annotated with @Service aka @Component which makes it eligible for autowiring. Why this class is not being picked up and autowired during unit tests?

JavaScript

The test failed to load application context,

JavaScript

Full stack trace

If test class is annotated with @SpringBootTest then it creates whole application context including database connection and a lot of unrelated beans which obviously not needed for this unit test(It won’t be unit test then!). What is expected is that only beans on which FooService depends should be instantiated, except which are mocked, with @MockBean.

Advertisement

Answer

You should use @SpringBootTest(classes=FooServiceImpl.class).

As it’s mentioned on Annotation Type SpringBootTest:

public abstract Class<?>[] classes

The annotated classes to use for loading an ApplicationContext. Can also be specified using @ContextConfiguration(classes=…). If no explicit classes are defined the test will look for nested @Configuration classes, before falling back to a SpringBootConfiguration search.

Returns: the annotated classes used to load the application context See Also: ContextConfiguration.classes()

Default: {}

This would load only necessary class. If don’t specify, it may load a database configuration and other stuff which would make your test slower.

On the other hand, if you want really want unit test, you can test this code without Spring – then @RunWith(SpringRunner.class) and @SpringBootTest annotations are not necessary. You can test FooServiceImpl instance. If you have Autowired/injected properties or services, you set them via setters, constructors or mock with Mockito.

Advertisement