2015-08-05 7 views
6

In meiner Spring-Boot-Anwendung habe ich eine Service-Bean (mit @ Service Annotation) und ich möchte diesen Dienst in bestimmten JUnit Test (nicht in allen Tests) zu verspotten. Wie kann ich diese Servicebohne für nur einen bestimmten Test ersetzen?Spring - ersetzen @Service Bean im Test

Dienst erklärt wie:

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

App Konfigurationsklasse:

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

public class Application { 
... 
} 

Prüfklasse:

@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); 
     } 

    } 
} 

Und Testklasse parent:

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

Aber das funktioniert nicht. Wenn ich den Test ausführe, wird das ursprüngliche LocalizationServiceImpl für die Eigenschaft autowired locService verwendet. Dies erschien in der Protokolldatei: Überspringende Bean-Definition für [BeanMethod: name = localizationService, declaringClass = ... LocalizationServiceTest $ LocalizationServiceTestConfig]: eine Definition für Bean 'localizationService' existiert bereits. Diese Top-Level-Bean-Definition wird als Überschreibung betrachtet.

Wenn ich anderen Namen für @Bean-Methode in LocalizationServiceTestConfig z. localizationServiceMock() (von der ursprünglichen Implementierung Klassennamen unterschiedlich zu sein), dann Frühling wirft

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

Also dachte ich, es richtig ist, den gleichen Namen zu verwenden.

Nur Arbeitslösung ist @Service Annotation von LocalizationServiceImpl Klasse und erstellen Konfiguration für normale (nicht getestet) app läuft wie

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

Dann im Test läuft die richtige Mock-Implementierung autowired zu entfernen.

Aber es sollte möglich sein, das gleiche über @ Service Annotation zu tun, sollte nicht?

Danke für den Rat.

Antwort

9

Eine Lösung gefunden: Umbenennen z. zu localizationServiceMock() in Klasse LocalizationServiceTestConfig und kommentieren Sie die Methode mit @Primary.

Aber warum Bean Bohnen mit der gleichen 'ID' neu zu definieren funktioniert nicht wie via XML-Config?