2015-08-05 17 views
6

Nella mia applicazione di avvio di primavera ho un bean di servizio (con annotazione @Service) e voglio prendere in giro questo servizio in particolare il test JUnit (non in tutti i test). Come posso sostituire questo bean di servizio per un solo test particolare?Spring - replace @Service bean in test

Servizio dichiarato come:

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

App classe di configurazione:

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

public class Application { 
... 
} 

classe Test:

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

    } 
} 

E classe di test genitore:

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

Ma questo non funziona. Quando eseguo il test, LocalizationServiceImpl originale viene utilizzato per la proprietà locService autowired. Questo è apparso nel file di registro: Definizione di bean di salto per [BeanMethod: name = localizationService, declaringClass = ... LocalizationServiceTest $ LocalizationServiceTestConfig]: esiste già una definizione per bean 'localizationService'. Questa definizione di bean di livello superiore è considerata come override.

Quando uso un nome diverso per il metodo @Bean in LocalizationServiceTestConfig, ad es. localizationServiceMock() (per essere diverso da nomeclasse implementazione originale) poi molla getta

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

Così ho pensato che è corretto utilizzare lo stesso nome.

soluzione Solo lavorando è quello di rimuovere @Service annotazioni dalla classe LocalizationServiceImpl e creare la configurazione per il normale (non prova) run app come

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

Poi nella prova di funzionamento della corretta implementazione mock è autowired.

Ma dovrebbe essere possibile fare lo stesso tramite l'annotazione @Service, non dovrebbe?

Grazie per il consiglio.

risposta

9

Trovato una soluzione da solo: rinomina localizationServiceImpl() ad es. a localizationServiceMock() nella classe LocalizationServiceTestConfig e annotare il metodo con @Primary.

Ma perché la ridefinizione del bean con lo stesso 'id' non funziona come tramite xml-config?

Problemi correlati