Search code examples
javaunit-testingmockitospring-restcontroller

During unit test of Restcontroller my Mocking class does not work


I need to test one method in RestController, with mock class. But java does not understand, then its mock class and try invoke it. However, such method with the same mock class works sucsesfuly. My RestController:

@RestController
public class OrderController {

    @Autowired
    ServiceOrder serviceOrder;

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/orders", method= RequestMethod.POST, produces={"application/json; charset=UTF-8"})
    public List<Order> sortOrders(@RequestParam("field") String field) {
        return serviceOrder.sortOrders(field);

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "/orders/completed/period", method= RequestMethod.POST, produces={"application/json"})
    public long showCompletedOrdersInPer(
            @RequestParam (value = "start") String startDate,
            @RequestParam (value = "end") String endDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(startDate, formatter);
        LocalDate end = LocalDate.parse(endDate, formatter);
        return serviceOrder.completedOrdersInPeriod(start, end);
    }

Well, test for method sortOrders() is OK, but test for showCompletedOrdersInPer() is failed. My test class:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {ControllersTestConfig.class})
@WebAppConfiguration
public class OrderControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Autowired
    OrderController orderController;

    @Autowired
    ServiceOrder serviceOrder;

    private MockMvc mockMvc;
    @BeforeEach
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
    }

    // Test from method OrderController.sortOrders
    // Description: we should get response.status OK
    @Test
    public void sortOrdersTest() throws Exception {
        Mockito.when(serviceOrder.sortOrders(any())).thenReturn(null);
        mockMvc.perform(MockMvcRequestBuilders.post("/orders?field=1")).andExpect(MockMvcResultMatchers.status().isOk());
    }

    // Test from method OrderController.showCompletedOrdersInPer
    // Description: we should get response.status OK
    @Test
    public void showCompletedOrdersInPerTest() throws Exception {
        Mockito.when(serviceOrder.completedOrdersInPeriod(any(), any())).thenReturn(1L);
        mockMvc.perform(MockMvcRequestBuilders.post("/orders/completed/period?start=2020-01-01&end=2022-01-01")).andExpect(MockMvcResultMatchers.status().isOk());
    }

And this is configClass:

public class ControllersTestConfig {

    @Bean
    public ServiceOrder serviceOrder() {
        return Mockito.mock(ServiceOrder.class);
    }
    
    @Bean
    public OrderController orderController(){
        return new OrderController();
    }

}

When i run sortOrdersTest(), test is ok, when i run showCompletedOrdersInPerTest(), i have

Status expected:<200> but was:<500>
Expected :200
Actual   :500

If i run tests with debug, i see, then in sortOrders() mock works and serviceOrder.sortOrders(field) does not invoke, and in showCompletedOrdersInPer() mock does not work and java try invoke serviceOrder.completedOrdersInPeriod(start, end) and i have status 500. Please, help me!


Solution

  • Well, it was a problem with parsing Integer to Long in dao layer. I resolve it and test is done.