2012-06-12 5 views
16

Unser Web-App SystemPropertyPlaceholder eine Spring Web App testen verwendet Eigenschaftsdateien auf dem Wert einer Systemeigenschaft (siehe unten) lokalSet Systemeigenschaft für JUnit Runner (Eclipse)

Den Standard-Setup abhängig laden zum Laufen ist in application.properties gespeichert. Auf dem Produktionsserver setzen wir gerade "env" auf "production", bevor wir die App bereitstellen und es lädt production.properties.

Jetzt zum Testen der App sollte eine test.properties Datei verwendet werden.

Wenn ich alle Tests, sagen wir in unserem jenkins Build, laufen lasse, wird -Denv=test wie erwartet funktionieren. Aber was, wenn ich nur einen einzigen Test in Eclipse mit dem integrierten JUnit Runner ausführen möchte?

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader = WebContextLoader.class, locations = {"classpath:application-context.xml" }) 
public class SomeTest { 

Gibt es eine Möglichkeit meinen Test zu sagen, sollte es die Systemeigenschaft „env“ auf „Test“ einstellen, bevor Frühling geladen wird? Da MethodInvokingFactoryBean Verwendung setzt sie erst danach aus irgendeinem Grund, auch wenn ich es einstellen, bevor mein Eigentum Dateien laden:

<bean id="systemPrereqs" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" value="#{@systemProperties}" /> 
    <property name="targetMethod" value="putAll" /> 
    <property name="arguments"> 
     <!-- The new Properties --> 
     <util:properties> 
      <prop key="env">test</prop> 
     </util:properties> 
    </property> 
</bean> 

<bean 
    class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> 
    <property name="searchContextAttributes" value="true" /> 
    <property name="contextOverride" value="true" /> 
    <property name="ignoreResourceNotFound" value="true" /> 
    <property name="locations"> 
     <list> 
      <value>classpath:application.properties</value> 
      <value>classpath:${env}.properties</value> 
      <value>${config}</value> 
     </list> 
    </property> 
</bean> 

<bean id="managerDataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="username"> 
     <value>${database.username}</value> 
    </property> 
    <property name="password"> 
     <value>${database.password}</value> 
    </property> 
    <property name="url"> 
     <value>${database.url}</value> 
    </property> 

</bean> 

Mit den Datenbank-Eigenschaften definiert innerhalb application.properties, production.properties und test.properties.

Der Punkt ist natürlich, dass ich die gleiche Kontextdatei für alle Umgebungen verwenden möchte, sonst könnte ich meinen Test einfach einen anderen Kontext verwenden, wo ich die PropertyPlaceholder-Eigenschaft "location" auf test.properties setzt. Aber ich möchte, dass meine Tests auch meinen Kontext abdecken, damit eventuelle Fehler so früh wie möglich aufgedeckt werden (Ich mache End-to-End-Tests auf unserer Web-App mit spring-web-mvc, das die gesamte Web-App mit einigen lädt schönes Feedback dort und ich will das nicht verlieren).

Bisher ist die einzige Art, wie ich die JUnit runner enthalten einige System-Eigenschaft Argument könnte sein, sehen zu konfigurieren, obwohl ich weiß nicht, wie das zu tun ..

+0

Ich würde die ordnungsgemäße Verwendung Profile in diesen Profilen sagen importieren Dateien, die Sie brauchen. Sieht so aus, als erfindest du das Rad neu. Mit Profil können Sie einfach '@ ActiveProfiles' zu Ihrem Testfall hinzufügen, um die richtigen Dinge zu laden. Statt od '-Denv = test' würdest du' -Dressing.active.profiles = test' verwenden. –

Antwort

33

ich genau bin auf die gleiche Problem jetzt und hoffentlich den Weg gefunden. Sie können System.setProperty() in den statischen Initialisierer Ihres Testfalls aufrufen.

+0

Cool, funktioniert! Vielen Dank! :) – Pete

+1

Während dies funktioniert, wenn ein einzelner Test ausgeführt wird, funktioniert es möglicherweise nicht unbedingt, wenn mehrere Tests ausgeführt werden, da der Spring-Kontext in mehreren Tests wiederverwendet werden kann. – pimlottc

+0

@pimlottc, IMHO Ausführen mehrerer Tests verursacht in diesem Fall kein Problem. Der Catch ist, dass wir die Systemeigenschaft vor der Initialisierung des Spring-Kontextes setzen müssen. Dies wird durch Verwendung eines statischen Initialisierers erreicht. Wenn alle Testfälle, die den gleichen Spring-Kontext haben, diese Eigenschaft setzen (das ist der Fall), wird der Spring-Kontext korrekt initialisiert. – AlexR

16

In Eclipse klicken Sie mit der rechten Maustaste auf die JUnit-Testklasse, wählen Sie Ausführen als> Konfigurationen ausführen ..., gehen Sie zur Registerkarte Argumente, und fügen Sie unter VM-Argumente den Systemeigenschaftseintrag ein. -Dcatalina.base = C: \ Programme \ Apache-tomcat-7.0.32

+3

Gibt es eine Möglichkeit, dies standardmäßig für alle Tests zu tun, sodass Sie diese Eigenschaft nicht für jeden Test manuell festlegen müssen? – Stewart

0

Sie könnten versuchen, depends-on Attribut zu verwenden Verfahren vor anderen Bean laufen Aufruf haben