2016-06-02 5 views
2

Ich habe einen Arbeitstest für JUnit mit Mockito gemacht und versucht, es an die Arbeit mit TestNG anzupassen, aber seltsamerweise mit TestNG nur ein Test funktioniert.Verwenden von Mockito mit TestNG

Ich denke, es ist irgendwie mit dem Zurücksetzen der Mocks in Verbindung, aber ich habe herum mit Versuchen versucht, Mockito.reset aufrufen und BeforeMethod und BeforeClass und verschiedene Kombinationen zu verwenden, aber immer noch nur einen Test zu bestehen.

Was muss ich tun, damit der Test funktioniert?

@BeforeClass 
public void setUp() {  
    MockitoAnnotations.initMocks(this);         
    mockMvc = MockMvcBuilders.standaloneSetup(calculatorController).build(); 
} 

@AfterMethod 
public void reset() { 
    Mockito.reset(calculatorService); 
} 

@Test 
public void addFunctionTest() throws Exception {    
    Assert.assertNotNull(calculatorController); 
    Result expectedResult = new Result(); 
    expectedResult.setResult(10); 

    when(calculatorService.add(anyInt(), anyInt())).thenReturn(expectedResult);        

    mockMvc.perform(get("/calculator/add").accept(MediaType.APPLICATION_JSON_VALUE) 
      .param("val1", "100") 
      .param("val2", "100")) 
    .andExpect(content().contentType("application/json")) 
    .andExpect(status().isOk()) 
    .andExpect(jsonPath("$.result", equalTo(10)));  

    verify(calculatorService, times(1)).add(anyInt(), anyInt()); 
} 

@Test 
public void subtractFunctionTest() throws Exception {    
    Assert.assertNotNull(calculatorController); 
    Result expectedResult = new Result(); 
    expectedResult.setResult(90); 

    when(calculatorService.subtract(anyInt(), anyInt())).thenReturn(expectedResult);         

    mockMvc.perform(get("/calculator/subtract").accept(MediaType.APPLICATION_JSON_VALUE) 
    .param("val1", "100") 
    .param("val2", "10")) 
    .andExpect(content().contentType("application/json")) 
    .andExpect(status().isOk()) 
    .andExpect(jsonPath("$.result", equalTo(90)));  

    verify(calculatorService, times(1)).subtract(anyInt(), anyInt()); 
} 

Der zweite Test scheint immer bei Behauptungen fehlzuschlagen, dass entweder der Inhaltstyp nicht festgelegt ist oder das erwartete Ergebnis falsch ist.

Es scheint, als ob die Antwort für den ersten Test irgendwie im zweiten Test ausgewertet wird und so offensichtlich falsch ist!

Ich weiß, dass der Controller und der Service wie erwartet funktionieren und genau die gleichen Tests, die mit jUnit laufen, funktionieren in Ordnung.

Ich habe es geschafft, wenn sie richtig auszuführen, um die Tests zu bekommen nur die folgende ich tun:

@BeforeGroups("subtract") 
public void reset() {  
    Mockito.reset(calculatorService); 
    mockMvc =  MockMvcBuilders.standaloneSetup(calculatorController).build(); 
} 

@Test(groups = "subtract") 
public void subtractFunctionTest() throws Exception {  
    System.out.println("***** IN METHOD *****"); 
    Assert.assertNotNull(calculatorController); 
    Result expectedResult = new Result(); 
    expectedResult.setResult(90); 

    when(calculatorService.subtract(anyInt(), anyInt())).thenReturn(expectedResult);         

    //Perform HTTP Get for the homepage 
    mockMvc.perform(get("/calculator/subtract").accept(MediaType.APPLICATION_JSON_VALUE) 
    .param("val1", "100") 
    .param("val2", "10")) 
    .andExpect(content().contentType("application/json")) 
    .andExpect(status().isOk()) 
    .andExpect(jsonPath("$.result", equalTo(90)));  

    //Verify that the service method was only called one time 
    verify(calculatorService, times(1)).subtract(anyInt(), anyInt()); 
} 

Das bedeutet, dass ich, obwohl eine dieser Reset-Methoden für jede Testmethode hinzufügen müssen, und ich muss dann eine Gruppe pro Testmethode, die nicht korrekt erscheint.

+0

Welche Bibliothek verwenden Sie für Assertions ('Result expectedResult = new Result()')? –

+0

Sie setzen nach jeder Methode einen Mock zurück, aber Sie tun nichts mit 'mocMvc'. Kann dies Ihre Tests beeinflussen? Kannst du das überprüfen, indem du '@ BeforeClass' in' @ BeforeMethod' änderst? –

+0

Hallo Eugen, ich habe versucht herumzuspielen und es funktionierten keine Kombinationen. Ich werde meinen Beitrag mit dem aktualisieren, was ich geschafft habe zu arbeiten, aber es würde eine Menge Code-Wiederholung bedeuten. – berimbolo

Antwort

4

Es gibt einen Unterschied im Verhalten dieser Frameworks:

  • JUnit für jeden seiner Testmethoden eine neue Instanz der Klasse erstellt. Dies bedeutet, dass die Felder nicht zwischen den Tests geteilt werden.
  • Aber TestNG schafft nur ein Objekt und damit der Staat in den Feldern wird geteilt zwischen zu @Test s

Für Mockito müssen Sie Mocks vor jeder Testmethode init so dass der Staat nicht zwischen zwei @Test s geteilt wird in TestNG:

@BeforeMethod 
public void init() { 
    MockitoAnnotations.initMocks(this); 
} 

Für JUnit funktioniert es von Box, weil der 2. @Test seine eigene Felder hat und seine eigene spottet.

+0

Ich habe dies versucht und es funktioniert nicht, die Ergebnisse der Anrufe kommen in der falschen Reihenfolge zurück. Also, wenn meine Add-Methode ein Ergebnis von 5 erwartet und meine Subtraktionsmethode ein Ergebnis von 10 erwartet, wird mein Add-Test manchmal mit einem Assertionsfehler fehlschlagen, dass er 10 und erwartete 5 erhält. – berimbolo

+0

Sind Sie sicher, dass Sie '@ BeforeMethod' verwenden '@ BeforeClass'? –

+0

Ich habe sowohl BeforeMethod als auch BeforeClass ausprobiert. Der Test macht einen echten Anruf bei der Steuerung und verspottet die Dienstantwort, so dass ich nicht sehe, wie die Ergebnisse verwechselt werden können. Der einzige Weg, wie ich die Tests zum Laufen bringen konnte, bestand darin, die Gruppen zu verwenden und jeder Methode eine Gruppe zuzuweisen und dann die Annotation der Vorher-Gruppen zurückzusetzen, aber ich werde es noch einmal mit BeforeMethod versuchen und in Kürze wiederkommen, weil ich Mockito anrief .Reset in einer AfterMethod-Annotation. – berimbolo