javamockingmockitospringjunit4classrunner

Service object not mocked with data?


Service object not mocked from controller testcase return empty object here is the below code 

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = Main.class)
    @WebAppConfiguration
    @ActiveProfiles(ApplicationConstants.DEVELOPMENT_PROFILE)
    public class EmployeeControllerTest {
    @Autowired
    private WebApplicationContext   webAppContext;
    private MockMvc mockMvc;

    @Mock
    EmployeeCompositeService  employeeCompositeService;
    @InjectMocks 
    EmployeeController employeeController;

    String name = "mike";

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testGetEmployees() throws Exception {

        Mockito.when(employeeCompositeService.getEmployeesByName(name)).thenReturn(getEmployees());
        String url = URIConstants.ROOT_CONTEXT + URIConstants.EMPLOYEE;
        MvcResult result =
        mockMvc.perform(post(url)
                        .contentType(APPLICATION_JSON_UTF8)
                        .content(convertObjectToJsonBytes(name))
                        .andExpect(status().isOk())
                        .andExpect(content().contentType(APPLICATION_JSON_UTF8))
                        .andExpect(jsonPath("$[0].employeeName").value("Mike"))
                        .andReturn();
        String jsonContent = result.getResponse().getContentAsString();
        LOGGER.debug("jsonContent: {}",jsonContent);

    }

    protected byte[] convertObjectToJsonBytes(Object object) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsBytes(object);
    }

    private List<Employee> getEmployees(){
    //here is the logic to get List of employees to return. When the mockito call is invoked.
    }

    }

@RestController
@RequestMapping(value = URIConstants.ROOT_CONTEXT)
public EmployeeController{
@Autowired
private EmployeeCompositeService employeeCompositeService;

    @RequestMapping(value=URIConstants.EMPLOYEE, method=RequestMethod.POST, consumes = INPUT_FORMAT, produces = OUTPUT_FORMAT)
    public List<Employees> getEmployees(@RequestBody String name){
        return employeeCompositeService.getEmployeesByName(name); //When invoke this method it calls inner service but not returns the mocked object.

    }
}

I have a service call in side EmployeeController i.e

employeeCompositeService.getEmployees(String name)

So I have mocked in the EmployeeControllerTestcase i.e

@Mock EmployeeCompositeService  employeeCompositeService;

when I run the controller testcase it invokes further services calls and repository and hit the database

So I doesn't want to call inner services returns the results form this call employeeCompositeService.getEmployeesByName(name); from controller.

Can you please tell me what I did wrong in the above code Thanks in Advance


Solution

  • The EmployeeCompositeService mock object is created but isn't injected anywhere. This is initialising a class member in the test but since it is not being injected into the controller, the real, database-facing implementation is being used. To inject the mock into the controller, declare the controller as a class member in the test and annotate it using the org.mockito.InjectMocks annotation. This will take the class members from the test with the @Mock annotation and inject them into the fields of controller that implement the same interface.

    The next step is to inject the controller into the MockMvc object by assigning it as mockMvc = MockMvcBuilders.standaloneSetup(employeeController).build().