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.