0

Ich versuche, eine Spring-Rest-Controller-Klasse mit JUnit, Mockito, Federtest und Spring Security Test zu testen. Das Folgende ist meine Ruhe-Controller-Klasse, für die ich den Test durchführe;Mockito-Fehler: Eigentlich gab es keine Interaktionen mit diesem Mock

@RestController 
public class EmployeeRestController { 

    @Autowired 
    private EmployeeService employeeService; 

    @PreAuthorize("hasAnyRole('ROLE_EMPSUPEADM')") 
    @RequestMapping(value = "/fetch-timezones", method = RequestMethod.GET) 
    public ResponseEntity<List<ResponseModel>> fetchTimeZones() { 
     List<ResponseModel> timezones = employeeService.fetchTimeZones(); 
     return new ResponseEntity<>(timezones, HttpStatus.OK); 
    } 

} 

Das Folgende ist meine Testklasse;

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {SpringConfiguration.class}) 
@WebAppConfiguration 
public class EmployeeRestControllerUnitTest { 

private MockMvc mockMvc; 

@Autowired 
private WebApplicationContext webApplicationContext; 

@Mock 
private EmployeeService employeeService; 

@InjectMocks 
private EmployeeRestController employeeRestController; 

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 
    Mockito.reset(employeeService); 
    mockMvc = MockMvcBuilders 
       .webAppContextSetup(webApplicationContext) 
       .build(); 
} 

@Test 
@WithMockUser(roles = {"EMPSUPEADM"}) 
public void testFetchTimezones() { 
    try { 
     mockMvc.perform(get("/fetch-timezones")) 
      .andExpect(status().isOk())    
      .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 
      .andExpect(jsonPath("$", hasSize(4))); 
     verify(emploeeService, times(1)).fetchTimeZones(); 
     verifyNoMoreInteractions(employeeService); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

machte ich die oben Test-Klasse von vielen Tutorials beziehen. Das Problem ist, dass ich nicht alles klar verstehen kann. Also habe ich die folgenden Zweifel.

  1. Ich bin ein Modell von EmployeeService zu schaffen und es in EmployeeRestController Injektion @InjectMocks verwenden, dann, warum ich die folgende Versagen bekommen;

    Wanted but not invoked: 
    careGroupService.fetchTimeZones(); 
    -> at com.example.api.test 
    .restcontroller.EmployeeRestControllerUnitTest 
    .testFetchTimezones(EmployeeRestControllerUnitTest.java:73) 
    Actually, there were zero interactions with this mock. 
    
  2. Wie funktioniert MockMvcBuilders.webAppContextSetup (WebApplicationContext) .build(); funktioniert genau.

  3. Ich weiß, dass MockMvcBuilders.standaloneSetup (employeeRestController) zum Testen einzelner Controller-Klassen und Feder-Konfiguration für diese Methode nicht verfügbar ist. Wie können wir für diese Methode eine Federkonfiguration bereitstellen, ist das möglich?

  4. Schließlich, wie funktioniert dieses Stück Code: Mockito.reset (employeeService); funktioniert.

Antwort

1

1) Sie überprüfen, für

verify(emploeeService, times(1)).fetchTimeZones(); 

aber Sie haben nicht Setup Mock Verhalten für sie (bevor Sie anrufen mockMvc.perform(get("/fetch-timezones"))).

List<ResponseModel> timezones = new ArrayList<>(); 
when(emploeeService.fetchTimeZones()).thenReturn(timezones); 

2) Erstellen Sie MockMvc aus dem Kontext. mockmvc emuliert Webcontainer, verwendet Mock für alle, wo es möglich ist, unterstützt aber http-Aufrufe und gab die Möglichkeit, Controller aufzurufen.

Es steht den Dispatcher Servlet und alle erforderlichen MVC Komponenten auf, ermöglicht es uns, einen Endpunkt in einer richtigen Web-Umgebung zu testen, aber ohne den Overhead einen Server ausgeführt wird.

3), wenn Sie verwenden:

@MockBean private EmployeeService employeeService; 

Sie echten Service außer Kraft setzen. Entferne es aus der Testklasse. Der echte Dienst wird beim Testen verwendet. Benutze @Mock statt @MockBean. @MockBean es durch Container überschreiben ist, mit @Mock müssen Sie diese

durch Reflexion in die Steuerung injizieren

oder ohne Federschuh mit Reflexion:

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 
    Mockito.reset(employeeService); 
    mockMvc = MockMvcBuilders 
       .webAppContextSetup(webApplicationContext) 
       .build(); 
    EmployeeRestController employeeRestController= 
      webAppContext.getBean(EmployeeRestController.class); 
    ReflectionTestUtils.setField(employeeRestController, 
           "employeeService", 
           employeeService); 
} 

4) Mockito.reset(employeeService); - Sie alle Verhaltensweisen zurückgesetzt, die Sie vor setupped. Mock enthält Informationen von when(), verify() und steuert es, Call Reset - es ist sauber alle Informationen.

+0

Hallo, danke für deine Antworten. Aber ich bekomme immer noch die gleiche Fehlermeldung. – karthi

+0

Entschuldigung, ich benutze keinen Springboot. – karthi

+0

Vielen Dank für Ihre Hilfe, ich konnte es erreichen, indem Sie einen ** Test Kontext ** wie in diesem [Link] vorgeschlagen (https://stackoverflow.com/questions/37369768/should-mockito-be-used-with -mockmvcs-webappcontextsetup-in-spring-4) – karthi

Verwandte Themen