2010-04-09 15 views
43

Federstütze JUnit ganz gut auf, dass: Mit der RunWith und ContextConfiguration Anmerkung sieht sich sehr intuitivFrühling Dependency Injection mit TestNG

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:dao-context.xml") 

Dieser Test in der Lage sein wird, sowohl in Eclipse & Maven in korrekt zu funktionieren. Ich frage mich, ob es für TestNG ähnliche Sachen gibt. Ich überlege, auf dieses "Next Generation" -Framework umzusteigen, aber ich habe keine Übereinstimmung gefunden, um mit Spring zu testen.

Antwort

51
+0

Dank. Genau das suche ich. –

+4

Was für ein Chaos. Zuerst erzwingt bestimmte Klassenhierarchie. Zweitens ist es ziemlich verwirrend, dass ein Testfall, der '@ Transactional 'verwendet, die nicht-transaktionale Version versehentlich erweitert. Leider gibt es keine andere Möglichkeit, einen Spring mit TestNG zu verwenden. –

+0

@GrzesiekD. Ich hoffe, dass sich in 4,5 Jahren etwas geändert hat. :) Also bitte überprüfen Sie den Status quo. – lexicore

23

Hier ist ein Beispiel, das für mich gearbeitet:

import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 
import org.testng.annotations.Test; 

@Test 
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 
public class TestValidation extends AbstractTestNGSpringContextTests { 

    public void testNullParamValidation() { 
     // Testing code goes here! 
    } 
} 
17

Frühling und T estNG funktioniert gut zusammen, aber es gibt einige Dinge, die man beachten sollte. Abgesehen von der Unterklasse von AbstractTestNGSpringContextTests müssen Sie wissen, wie sie mit Standard-TestNG-Setup-/Teardown-Annotationen interagiert.

TestNG hat vier Ebenen der Einrichtung

  • BeforeSuite
  • BeforeTest
  • BeforeClass
  • Vorbearbeitungsmethode

die genau auftreten, wie Sie (gutes Beispiel für Selbst dokumentieren APIs würde erwarten,). Diese haben alle einen optionalen Wert namens "dependsOnMethods", der einen String oder String [] annehmen kann, wobei Name oder Name (n) der Methoden auf derselben Ebene stehen.

Die Klasse "AbstractTestNGSpringContextTests" verfügt über eine Annotated-Methode "BeforeClass" mit dem Namen "springTestContextPrepareTestInstance", von der Sie abhängig davon abhängig sein müssen, ob Sie eine AutoWire-Klasse verwenden. Bei Methoden müssen Sie sich nicht um das Autowiren kümmern, da es auftritt, wenn die Testklasse vor der Klassenmethode eingerichtet wird.

Das lässt nur die Frage offen, wie Sie eine autowired Klasse in einer mit BeforeSuite annotierten Methode verwenden könnten. Sie können dies tun, indem Sie springTestContextPrepareTestInstance manuell aufrufen - während dies nicht standardmäßig eingerichtet ist, habe ich es mehrmals erfolgreich durchgeführt.

Also, zu veranschaulichen, die eine modifizierte Version des Beispiels des Arup:

import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 
import org.testng.annotations.Test; 

@Test 
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 
public class TestValidation extends AbstractTestNGSpringContextTests { 

    @Autowired 
    private IAutowiredService autowiredService; 

    @BeforeClass(dependsOnMethods={"springTestContextPrepareTestInstance"}) 
    public void setupParamValidation(){ 
     // Test class setup code with autowired classes goes here 
    } 

    @Test 
    public void testNullParamValidation() { 
     // Testing code goes here! 
    } 
} 
+0

Die Methode org.springframework.test.context.testng.AbstractTestNGSpringContextTests # springTestContextPrepareTestInstance hat bereits die Annotation @BeforeClass, sodass diese Lösung für mich redundant erscheint. –

+1

Diese Lösung ermöglicht es Ihnen, Ihrem Test autowire-feldabhängigen Code hinzuzufügen. "springTestContextPrepareTestInstance" ist eine "before class" -Methode und garantiert nicht, dass es vor der "before class" einer Unterklasse ausgeführt wird - Sie müssen das dependsOnMethods-Feld explizit setzen – romeara

+2

Das funktioniert leider nicht für mich. Standardmäßig scheint der '@ Autowire' SEHR spät zu sein, nach @BeforeTest (aber vor @Test). Ich habe versucht, die dependsOnMethods hinzufügen, aber dann bekomme ich: MyClass ist abhängig von der Methode geschützt void org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance() löst java.lang.Exception, die nicht mit @Test annotiert ist ... – dmansfield