Ho eseguito i problemi @ComponentScan
con le classi @Configuration
per i test, ovvero lo @ComponentScan
sta eseguendo il test non previsto @Configuration
durante i test di integrazione.Esclusa configurazione nelle classi di test da @ComponentScan
Per esempio, diciamo che hai una certa configurazione globale in src/main/java
che tira nei componenti all'interno com.example.service
, com.example.config.GlobalConfiguration
:
package com.example.config;
...
@Configuration
@ComponentScan(basePackageClasses = ServiceA.class)
public class GlobalConfiguration {
...
}
E 'destinato a tirare in due servizi, com.example.services.ServiceA
e com.example.services.ServiceB
, annotata con @Component
e @Profile("!test")
(omesso per brevità).
Poi in src/test/java, com.example.services.ServiceATest
:
package com.example.services;
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ServiceATest.ServiceATestConfiguration.class)
public class ServiceATest {
...
@Configuration
public static class ServiceATestConfiguration {
@Bean
public ServiceA serviceA() {
return ServiceA(somemocking...);
}
}
}
E anche com.example.ServiceBIntegrationTest
, che deve tirare in GlobalConfiguration.class
per essere un test di integrazione, ma evita ancora tirando in implementazioni pericolose @ActiveProfiles("test")
:
package com.example.services;
...
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {GlobalConfiguration.class, ServiceBIntegrationTest.ServiceBIntegrationTestConfiguration.class})
public class ServiceBIntegrationTest {
...
@Configuration
public static class ServiceBIntegrationTestConfiguration {
@Bean
public ServiceB serviceB() {
return ServiceB(somemocking...);
}
}
}
l'evidente intenzione del ServiceBIntegrationTest
è tirare nella configurazione completa applicazione tramite src/main/java
GlobalConfiguration
, escludere pericoloso componenti tramite @ActiveProfiles("test")
e sostituire quei componenti esclusi con le proprie implementazioni. Tuttavia, durante i test vengono combinati lo spazio dei nomi di src/main/java
e src/test/java
, pertanto di trova più nel classpath di quanto normalmente farebbe, ovvero il bean ServiceA
definito in ServiceA.ServiceATestConfiguration
. Ciò potrebbe facilmente portare a conflitti e risultati non intenzionali.
Ora, si potrebbe fare qualcosa su GlobalConfiguration
come @ComponentScan(..., excludeFilters= @ComponentScan.Filter(type = FilterType.REGEX, pattern = "\\.*(T|t)est\\.*"))
, ma questo ha problemi a sé stanti. Affidarsi alle convenzioni sui nomi è piuttosto fragile; tuttavia, anche se si è annullata un'annotazione @TestConfiguration
e si utilizza FilterType.ANNOTATION
, si sta effettivamente rendendo il vostro src/main/java
consapevole del proprio src/test/java
, che non dovrebbe essere, IMO (vedere nota di seguito).
Così com'è, ho risolto il problema utilizzando un profilo aggiuntivo. Su ServiceA
, aggiungo un nome profilo univoco, in modo che l'annotazione del profilo diventi qualcosa come @ActiveProfiles("test,serviceatest")
. Quindi, su ServiceATest.ServiceATestConfiguration
aggiungo l'annotazione @Profile("serviceatest")
. Ciò limita in modo efficace la portata del ServiceATestConfiguration
con relativamente poco in testa, ma sembra che sia:
a) Sto usando @ComponentScan
in modo non corretto, o
b) Ci dovrebbe essere un modello molto più pulito per la gestione di questo problema
Quale è?
nota: sì, l'applicazione è di test-aware perché sta usando @Profile("!test")
, ma direi che presenta la domanda un po 'di test-aware per la difesa contro l'utilizzo delle risorse improprio e rendendolo di test-aware per garantire la correttezza dei test sono cose molto diverse.
Sì, ci sono alcuni vantaggi a tale modello, ma non è quello che riguarda la mia domanda. Sto chiedendo come limitare al meglio l'ambito della configurazione all'interno di un pacchetto scansionato dal componente. – jwilner
La modifica della confezione sarebbe in conflitto con l'ambito locale del pacchetto, che è ovviamente importante per il test. Questo è insoddisfacente. – jwilner