2014-01-20 13 views
7

Ich habe eine Testklasse, die Lädt Spring @DirtiesContext den Spring-Kontext neu?

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:/test-context.xml"}) 
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) 
public abstract class TestClass { 
    @Rule @Resource public JUnitRuleMockery jMockContext; 

    public void test1() { 
    //Expectations and test 
    } 
    public void test2() { 
    //Expectations and test 
    } 
} 

und in test-context.xml Ich definiere die JUnitRuleMockery plus mehr Mock-Objekte durch ein factory-method, wie

<bean id="mockContextFactory" class="MockContextFactory" /> 

<bean id="jMockContext" factory-bean="mockContextFactory" factory-method="getContext" scope="prototype" /> 

<bean id="firstMock" factory-bean="mockContextFactory" factory-method="getFirstMock" /> 

<bean id="secondMock" factory-bean="mockContextFactory" factory-method="getSecondMock" /> 

MockContextFactory ist

public class MockContextFactory 
{ 
    private JUnitRuleMockery jUnitRuleMockery; 

    public MockContextFactory() { 
    jUnitRuleMockery = new JUnitRuleMockery(); 
    jUnitRuleMockery.setThreadingPolicy(new Synchroniser()); 
    } 

    public JUnitRuleMockery getContext() { 
    return jUnitRuleMockery; 
    } 

    public FirstMock getFirstMock() { 
    return jUnitRuleMockery.mock(FirstMock.class); 
    } 
    //others getter 
} 

wie

sieht in TestClass Ich habe mehrere Testmethoden und aufgrund der Anmerkungen @DirtiesContext erwarte ich, dass der Spring-Kontext nach jeder Testausführung erneut geladen wird (da jeder Test Erwartungen an Mock-Objekte setzt, muss ich den Spring-Kontext jedes Mal neu laden). Siehe @DirtiesContext from here. Es scheint jedoch, dass der Spring-Kontext nicht neu geladen wird: in der Tat, im Debug-Modus am Anfang von test2 eingeben (angeblich test1 wurde früher ausgeführt) kann ich sehen jMockContext immer noch Erwartungen, Ausführungsliste und Fehler (falls vorhanden) von test1 .
Also, um mit wenigen Fragen zu enden, verursacht wirklich @DirtiesContext Spring-Kontext neu geladen werden (wie ich von Spring Docs verstanden habe) oder habe ich die Annotation falsch verstanden? Im ersten Fall, was mache ich falsch? Wie kann ich in diesem Fall den Spring-Kontext für jeden Test neu laden?

EDIT, um das Problem zu begrenzen: Ich hatte einen Code wie das obige Beispiel von wenigen Tagen ausgeführt, dann habe ich heute einen neuen Test erstellt, in dem ich eine Erwartung hinzugefügt, die fehlgeschlagen ist. Dann sah ich alle anderen Tests in der Klasse aus dem gleichen Grund scheitern (während sie green bis heute waren). Debugging, ich fand heraus, dass jMockContext wurde nie gelöscht, was bedeutet, dass alle Tests wurden Erwartungen in den gleichen Pool hinzufügen: natürlich, solange keine Erwartung fehlgeschlagen, das war transparent und ich habe es nicht bemerkt (test1 fügt hinzu und übergibt einige Erwartungen, test2 nimmt einen nicht-leeren Pool von Erwartungen, die bereits bestanden und fügt seine eigenen hinzu, so gab es kein Problem), aber ich mag die vorherige Situation nicht und ich würde gerne jeden Test mit vorher festgelegten Erwartungen überhaupt beginnen.

Antwort

14

Hier ist meine Lösung. Ich weiß nicht, ob dies auf Spring 3.2 beschränkt ist oder ob es ein allgemeines Missverständnis ist, aber die Verwendung von @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) reicht nicht aus, um den gesamten Spring-Kontext für jeden Test neu zu laden. Ich musste auch die DirtiesContextTestExecutionListener in @TestExecutionListeners hinzufügen.
Also, am Ende, gearbeitet, was nur für mich war die Anmerkung von meiner TestClass zu

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:/test-context.xml"}) 
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) 
@TestExecutionListeners({DirtiesContextTestExecutionListener.class}) 
public abstract class TestClass 

nichts anderes ändern muss sich ändern.

+1

Vermutlich hatten Sie mehr als einen Test-Listener - in diesem Fall werden sie die Standard-Listener außer Kraft setzen, einschließlich des einen, um den Kontext zu beschmutzen, und sie von der Ausführung ausnehmen. Wahrscheinlich '' @DirtiesContext @TestExecutionListeners (Wert = {MyListener.class, OtherListener.class}, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) '' wird es auch tun. – phineas

+0

Yoy haben meinen Tag gerettet! –

Verwandte Themen