Home > Software engineering >  Does The program flow go deeper into the bean being mocked in MockMvc?
Does The program flow go deeper into the bean being mocked in MockMvc?

Time:05-05

From what I understand about mocking, the test should not go deeper into the bean being mocked. For example the control flow shouldn't go into the function apiService.getSomeData() and instead it should just return the string "Hello there". But is that how mocking works or does the program keep going deeper and should I be able to see the print statements of getSomeData() in the stdout?

When I actually run the code below, it doesn't go deeper. But is that how it's supposed to work?

Suppose this is the Rest Controller Code:

@RestController
@RequestMapping(value = "/testing")
public class ApiController {

    @Autowired
    ApiService service;

    @PostMapping(path = "/events/notifications",consumes = "application/json", produces = "application/json" )
    public ResponseEntity<String> checkMapping(@Valid @RequestBody String someData, @RequestHeader(value="X-User-Context") String xUserContext) throws Exception {
        String response  = service.getSomeData(someData);
        return ResponseEntity.status(HttpStatus.OK).body(response);
    }
}

Suppose this is the Controller test code:

@WebMvcTest(ApiController.class)
public class ApiControllerTest {

    @Autowired
    MockMvc mockMvc;
    @Autowired
    ObjectMapper mapper;

    @MockBean
    ApiService apiService;

    @Test
    public void testingApi() throws Exception {

        Mockito.when(apiService.getSomeData("")).thenReturn("Hello there");

        MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/testing/events/notifications")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .header("X-User-Context","something")
                .content("something");

        mockMvc.perform(mockRequest)
                .andExpect(status().isBadGateway());

    }
}

Suppose this is the Api Service code:

@Service
public class ApiServiceImpl implements ApiService{

    @Override
    public String getSomeData(String data) throws Exception {

        System.out.println("Going deeper in the program flow);

        callThisFunction();

        return "Some data";
    }

    public void callThisFunction(){
        System.out.println("Going two levels deeper");
    }
}

CodePudding user response:

In your test you are not talking to ApiServiceImpl at all, but an instance that is created by mockito and that is also implementing the ApiService interface. Therefore, your implementation of getSomeData() is not executed at all. That's what mocking is about. You create a "mock" implementation (or let a tool like mockito do it for you) of the thing you do not want to be executed and inject it instead of the "real" thing.

  • Related