mercredi 5 août 2015

Spring - replace @Service bean in test

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

Service declared as:

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

App configuration class:

@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages="my.package")
@EntityScan

public class Application {
...
}

Test 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 test class parent:

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

But this does not work. When I run the test then original LocalizationServiceImpl is used for autowired locService property. When I use different name for @Bean method in LocalizationServiceTestConfig e.g. testLocalizationServiceImpl() (to be different from original implementation classname) then spring throws

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

So I thought it is correct to use the same name.

Only working solution is to remove @Service annotation from LocalizationServiceImpl class and create configuration for normal (not test) app run like

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

Then in test run the correct mock implementation is autowired.

But it should be possible to do the same via @Service annotation, shouldn't?

Thanks for advice.

Aucun commentaire:

Enregistrer un commentaire