2014-10-15 13 views
6

Kann jemand eine Testressource hinzufügen (d. H. Eine, die nur für Testzwecke und nicht in run() -Methode der App hinzugefügt)? HierDropwizard Integrated Testing mit TestResource

ein Beispiel:

public class MyTest { 
    @ClassRule 
    public static final DropwizardAppRule<TestConfiguration> RULE = 
      new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-config.yaml"); 


    @BeforeClass 
    public static void setUpBeforeClass() throws Exception 
    { 
     MyTest.RULE.getEnvironment().jersey().register(new JustForTestingResource()); 
    } 


    @Test 
    public final void testTestResource() 
    { 
     Client client = new Client(); 

     ClientResponse response = client.resource(
      String.format("http://localhost:%d/rest/v1/test", RULE.getLocalPort())) 
      .get(ClientResponse.class); 

     assertThat(response.getStatus(), is(200)); 
    } 
} 

und

public class JustForTestingRessource { 


    @GET 
    @Path("test") 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getInTestResource() 
    { 
     return Response.status(Status.OK).type(MediaType.TEXT_PLAIN).entity("get @Path(\"test\") is ok").build(); 
    } 
} 

Mein Problem ist, dass die zugegebene Ressource hinzugefügt wird und ich Ressource nicht 404 Fehlerreaktion gefunden. Es scheint, dass ich die neue Ressource nach der Veröffentlichung von Ressourcen registriere und es gibt keine Aktualisierung in DropWizard nach dem Start.

Ich möchte nicht meine Application-Klasse erweitern und ich möchte Testcode nicht in meinen realen Anwendungscode einfügen. Weiß jemand, wie man die Testressource registriert, ohne sie in der Methode run() der Anwendung zu registrieren?

Dies funktioniert, aber eine neue Klasse benötigt wird:

public class TestService extends MyService{ 


    @Override 
    public void run(
     TestConfigurationconfiguration, 
     Environment environment) throws ClassNotFoundException 
    {  
     environment.jersey().register(new JustForTestingRessource()); 
     super.run(configuration,environment); 
    } 

} 

Anruf in JUnit wie bereits bekannt:

@ClassRule 
public static DropwizardAppRule<TestConfiguration> RULE = 
     new DropwizardAppRule<TestConfiguration>(TestService.class, "my-app-config.yaml"); 
+0

So etwas RULE.addRessource (...) wäre nette ... – user3280180

Antwort

5

Edit: Entfernen der vorherigen Antwort, weil es Ihr Problem nicht so gelöst hat, wie Sie es tun wollten.

Ich grub in die Umgebung Startup-Code und erkannte den Grund, warum die Registrierung einen Controller nicht zur Verfügung stellt, weil Anlegesteg bereits gestartet wurde. Wenn Sie den Anlegesteg stoppen, registrieren Sie Ihren Controller und starten Sie den Anlegesteg wieder, Ihre Ressource wird verfügbar sein und Sie können sie in Ihrem Test verwenden.

@BeforeClass 
public static void setUpBeforeClass() throws Exception 
{ 
    MyTest.RULE.environment.applicationContext.stop() 
    MyTest.RULE.environment.jersey().register(new JustForTestingResource()) 
    MyTest.RULE.environment.applicationContext.start() 
} 
+0

Ja aber dann habe ich auch noch zusätzlichen Testcode in meiner Anwendung. Um zu verhindern, dass es noch besser ist, eine Klasse zu erstellen, die MyApplication erweitert und run() wie oben erwähnt überschreibt. Aber ich habe nach einer besseren Lösung für das Hinzufügen einer Ressource nur in der TestClass gefragt, weshalb ich Ihrer Lösung nicht zustimmen kann. – user3280180

+0

Können Sie bitte erläutern, warum drei Codezeilen, die spezifisch für die Überprüfung einer Umgebungsvariablen sind, eine inakzeptable Option darstellen? – th3morg

+0

Ich vermeide Testcode in LiveCode, so dass sogar meine Klasse TestService MyService erweitert, ist eine bessere Lösung, weil ich in meiner Anwendung keine "nur zu Testzwecken" -Methoden habe. Mit dieser überschriebenen run() Methode kann ich meinen Test- und Livecode eindeutig trennen. Mit Ihrer Lösung wäre es möglich, eine falsche Konfiguration in Ihrem Live * .yml zu machen und dann haben Sie Codezeilen nur zum Testen in Ihrer Anwendung. – user3280180

2

Sie können die Ressourcen-Test selbst in einem Jersey Container ohne einen vollständigen Start dw -Beispiel.

Überprüfen Sie die "Testing Resources" section.

+0

Ich habe bereits Ressourcentests erstellt, aber ich habe einen neuen Filter eingefügt und deshalb brauche ich "eine vollständige dw-Instanz". – user3280180

0

hatte ich das ähnliche Problem mit dem @ClassRule, vielleicht kann es jemand helfen ..
In meinem Test (Groovy) der Aufruf von RULE.getApplication() oder getEnvironment() von @BeforeClass Methode zurückgegeben null:

def setupSpec() { 
    RULE.application.run() 
} 

java.lang.NullPointerException: Cannot invoke method run() on null object 
gezeigt

Ie RULE.testSupport hatte sowohl eine Nullanwendung als auch eine Umgebung.

Ich fand heraus, dass der Anruf an RULE.testSupport.vor() kurz vor run() den Fehler löst:

def setupSpec() { 
    RULE.testSupport.before() 
    RULE.application.run() 
} 

Und dann @AfterClass Methode:

def cleanupSpec() { 
    RULE.testSupport.after() 
} 

Oder benutzen Sie einfach @Rule statt @ClassRule und rufen

def setup() { 
    RULE.application.run() 
} 

innerhalb von @Before-Methode anstelle von @BeforeClass.
Obwohl es scheint seltsam, vielleicht gibt es eine andere bessere Lösung besteht ..

0

public class TestMain erstreckt Haupt {

public static void main(String ... args) throws Exception { 
    new TestMain().run(args); 
} 


@Override 
public void initialize(Bootstrap<AppConfiguration> bootstrap) { 
    super.initialize(bootstrap); 
    bootstrap.addBundle(
        new MigrationsBundle<AppConfiguration>() { 
         @Override 
         public DataSourceFactory getDataSourceFactory(
             AppConfiguration configuration) { 
          return configuration.getDataSourceFactory(); 
         } 
        }); 
} 

}

+0

einfach die Hauptklasse erweitern und dann testing-specific stuff dort sollte arbeiten, ich h2 in-mem DB nur zum Testen auf diese Weise – gli00001