Ich habe in @ComponentScan
Probleme mit @Configuration
Klassen für Tests - nämlich, die @ComponentScan
zieht unbeabsichtigt @Configuration
während Integrationstests.Ausschließen der Konfiguration in Testklassen von @ComponentScan
Zum Beispiel, sagen Sie einige globale config in src/main/java
haben, die innerhalb com.example.service
in Komponenten zieht, com.example.config.GlobalConfiguration
:
package com.example.config;
...
@Configuration
@ComponentScan(basePackageClasses = ServiceA.class)
public class GlobalConfiguration {
...
}
Es ist beabsichtigt ist in zwei Dienste zu ziehen, com.example.services.ServiceA
und com.example.services.ServiceB
, kommentierte mit @Component
und @Profile("!test")
(der Kürze halber weggelassen).
dann 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...);
}
}
}
Und auch com.example.ServiceBIntegrationTest
, die in GlobalConfiguration.class
zu ziehen, um braucht ein Integrationstest zu sein, aber immer noch vermeidet mit @ActiveProfiles("test")
in gefährlichen Implementierungen ziehen:
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...);
}
}
}
die offensichtliche Absicht der ServiceBIntegrationTest
ist in der kompletten src/main/java
Anwendungskonfiguration über GlobalConfiguration
ausschließen, gefährlich zu ziehen Komponenten über @ActiveProfiles("test")
und ersetzen diese ausgeschlossenen Komponenten durch eigene Implementierungen. Während der Tests werden jedoch die Namensräume und src/test/java
kombiniert, so dass GlobalConfiguration
@ComponentScan
mehr im Klassenpfad findet als normalerweise - nämlich die ServiceA
Bean, die in ServiceA.ServiceATestConfiguration
definiert ist. Das könnte leicht zu Konflikten und unbeabsichtigten Ergebnissen führen.
Jetzt könnten Sie etwas auf GlobalConfiguration
wie @ComponentScan(..., excludeFilters= @ComponentScan.Filter(type = FilterType.REGEX, pattern = "\\.*(T|t)est\\.*"))
tun, aber das hat seine eigenen Probleme. Sich auf Namenskonventionen zu verlassen ist ziemlich spröde; Dennoch, auch wenn Sie eine @TestConfiguration
Annotation zurückgenommen und FilterType.ANNOTATION
verwendet haben, würden Sie effektiv Ihre src/main/java
Ihrer src/test/java
bewusst machen, die es nicht sein sollte, IMO (siehe Hinweis unten).
So wie es aussieht, habe ich mein Problem mit einem zusätzlichen Profil gelöst. Unter ServiceA
füge ich einen eindeutigen Profilnamen hinzu - so dass seine Profilanmerkung etwa wie @ActiveProfiles("test,serviceatest")
aussieht. Dann, unter ServiceATest.ServiceATestConfiguration
, füge ich die Annotation @Profile("serviceatest")
hinzu. Dies begrenzt effektiv den Umfang des ServiceATestConfiguration
mit relativ wenig Aufwand, aber es scheint, als ob entweder:
a) Ich @ComponentScan
falsch verwenden, oder
b) Es sollte für den Umgang mit diesem Problem ein viel sauberes Muster seiner
Was ist das?
note: ja, die App ist Test bewusst, weil es @Profile("!test")
ist, aber ich würde behaupten, die Anwendung leicht Test-bewusst zu machen, gegen falsche Ressourcennutzung zu schützen und machen es Test-aware, um sicherzustellen, Die Richtigkeit der Tests sind sehr unterschiedliche Dinge.
Ja, es gibt einige Vorteile zu diesem Muster, aber das ist nicht, was meine Frage ist. Ich frage, wie man den Umfang der Konfiguration innerhalb eines Komponenten-gescannten Pakets am besten begrenzt. – jwilner
Das Ändern der Verpackung würde mit dem lokalen Scoping des Pakets kollidieren, was offensichtlich für das Testen wichtig ist. Dies ist nicht zufriedenstellend. – jwilner