Spring - replace @Service bean in test

In my spring boot application, I have a bean service (with @Service annotation) and I want to mock this service, in particular with the JUnit test (not in all tests). How can I replace this bean service with just one specific test?

Service is declared as:

@Service public class LocalizationServiceImpl implements LocalizationService { ... } 

Application Configuration Class:

 @Configuration @EnableAutoConfiguration @ComponentScan(basePackages="my.package") @EntityScan public class Application { ... } 

Testing Class:

 @Transactional @SpringApplicationConfiguration(classes = LocalizationServiceTest.LocalizationServiceTestConfig.class) public class LocalizationServiceTest extends ESContextTest { @Autowired private LocalizationService locService; @Configuration public static class LocalizationServiceTestConfig { @Bean public LocalizationService localizationServiceImpl() { return mock(LocalizationService.class); } } } 

And the parent of the test class:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public abstract class ESContextTest { ... } 

But that does not work. When I run the test, the original LocalizationServiceImpl is used for the autwired locService property. This appeared in the log file: Skipping the bean definition for [BeanMethod: name = localizationService, declaringclass = ... LocalizationServiceTest $ LocalizationServiceTestConfig]: the definition for the bean "localizationService" already exists. This top-level bean definition is considered an override.

When I use a different name for the @ Bean method in LocalizationServiceTestConfig, for example. localizationServiceMock () (to differ from the original name of the implementation class), then spring throws

 'No qualifying bean of type is defined: expected single matching bean but found 2: localizationServiceImpl,localizationServiceMock' 

So I thought it was right to use the same name.

The only working solution is to remove the @Service annotation from the LocalizationServiceImpl class and create a configuration for a regular (non-test) application running as

 @Configuration public class BeansConfig { @Bean public LocalizationService localizationServiceImpl() { return new LocalizationServiceImpl(); } } 

Then, in the test run, the correct layout implementation is performed.

But does one need to do the same with the @Service annotation, shouldn't it?

Thanks for the advice.

+6
source share
1 answer

Found a solution on my own: rename localizationServiceImpl() for example. before localizationServiceMock() in the LocalizationServiceTestConfig class and annotate the method using @Primary .

But why just overriding a bean with the same "id" doesn't work as through xml-config?

+9
source

All Articles