1

I'm new to testing controller and web layer. I have Service which has methods to work with orders, and I have controller that has that service as dependency

OrderService:

 @Service
    public class OrderServiceImpl implements OrderService{
        private OrderRepository orderRepository;
        private Assembler<Order, OrderDto> orderDtoAssembler;
        @Autowired
        public OrderServiceImpl(OrderRepository orderRepository,Assembler<Order, OrderDto> orderDtoAssembler) {
            this.orderRepository = orderRepository;
            this.orderDtoAssembler = orderDtoAssembler;
        }
    
        @Override
        @Transactional
        public List<OrderDto> findFilSortOrders(Map<String, String> filters, String sortedColumn, boolean descending, int startRow, int rowsPerPage) {
            return orderRepository.findFilSortOrders(filters, sortedColumn, descending, startRow, rowsPerPage)
                    .stream().map(orderDtoAssembler::mergeAggregateIntoDto).collect(Collectors.toList());
        }
    }

And Controller has several mapping and the one I want to test.

OrderController :

  @Controller
    public class OrderController {
        private static final Logger LOGGER = LogManager.getLogger(OrderController.class);
        private final CarCategoryService carCategoryService;
        private final TaxiServiceMakeOrder serviceMakeOrder;
        private final OrderService orderService;
        private final UserService userService;
    
        @Autowired
        public OrderController(CarCategoryService carCategoryService, TaxiServiceMakeOrder serviceMakeOrder, OrderService orderService, UserService userService) {
            this.carCategoryService = carCategoryService;
            this.serviceMakeOrder = serviceMakeOrder;
            this.orderService = orderService;
            this.userService = userService;
        }
    @GetMapping("/admin/ordersJson")
        @ResponseStatus(HttpStatus.OK)
        @ResponseBody
        public List<OrderDto> getOrders(@RequestParam String sortBy,
                                     @RequestParam String filter,
                                     @RequestParam boolean descending,
                                     @RequestParam int startRow,
                                     @RequestParam int rowsPerPage) throws JsonProcessingException {
            LOGGER.info("OrdersGetAction is invoked");
            ObjectMapper mapper = new ObjectMapper();
            Map<String, String> filters = null;
            if (!filter.equals("{}")) {
                filters = mapper.readValue(filter, new TypeReference<Map<String, String>>() {
                });
            }
            List<OrderDto> getOrders = orderService.findFilSortOrders(filters, sortBy, descending, startRow, rowsPerPage);
                System.out.println("Controller :"+getOrders.size());;//to check If it works
            LOGGER.info("Filtered and Sorted Order count is {}", getOrders.size());
            return getOrders;
        }

}

My test util to generate dto :

 public class OrderDtoUtil {
        public static List<OrderDto> generateOrderDto(int count) {
    
            return IntStream.range(0, count)
                    .mapToObj(i -> {
                        OrderDto orderDto = new OrderDto();
                        orderDto.setOrderId((long) i);
                        orderDto.setOrderDate(LocalDateTime.now());
                        orderDto.setOrderCost(500);
                        orderDto.setUserDestination("UserDestination");
                        orderDto.setUserAddress("UserAddress");
                        orderDto.setUserId((long) i);
                        orderDto.setCarId((long) i);
                        return orderDto;
                    }).collect(Collectors.toList());
    
        }
}

My test class for controller :

class OrderControllerTest {
    private CarCategoryService carCategoryService;
    private TaxiServiceMakeOrder serviceMakeOrder;
    private OrderService orderService;
    private UserService userService;
    private OrderController orderController;
    private MockMvc mockMvc;

    @BeforeEach
    public void setUp() {
        carCategoryService = mock(CarCategoryService.class);
        serviceMakeOrder = mock(TaxiServiceMakeOrder.class);
        orderService = mock(OrderService.class);
        userService = mock(UserService.class);
        orderController = new OrderController(carCategoryService, serviceMakeOrder, orderService, userService);
        mockMvc = standaloneSetup(orderController)
                .defaultRequest(get("/")
                        .contextPath("/petProject_war_exploded")
                        .accept(MediaType.ALL)).build();
    }

    @Test
    void getOrders() throws Exception {
        List<OrderDto> orderDtos = OrderDtoUtil.generateOrderDto(3);
        System.out.println("TEST method :"+orderDtos.size());
        when(orderService.findFilSortOrders(anyMap(), anyString(), anyBoolean(), anyInt(), anyInt())).thenReturn(orderDtos);
        mockMvc.perform(get("/petProject_war_exploded/admin/ordersJson")
                        .param("filter", "{}")
                        .param("sortBy", "orderId")
                        .param("descending", "false")
                        .param("startRow", "0")
                        .param("rowsPerPage", "3"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(3)))
                .andExpect(jsonPath("$[0].orderId", is(orderDtos.get(0).getOrderId())))
                .andExpect(jsonPath("$[1].orderId", is(orderDtos.get(1).getOrderId())))
                .andExpect(jsonPath("$[2].orderId", is(orderDtos.get(2).getOrderId())));

    }
}

And It fails on hasSize method because It shows that size is 0. Result :

enter image description here

Can you explain why does it happen?

DozezQuest
  • 179
  • 7
  • @Meninx-メネンックス I removed context path and set url to /admin/ordersJson but problem was not solved – DozezQuest Aug 28 '21 at 13:08
  • I have run into something similar when the controller was returning XML vs JSON. Play with the MediaType or Jackson annotations. Look at this other question as well which seems related: https://stackoverflow.com/questions/53514532/matching-object-in-json-with-jsonpath-in-spring-boot-test – Omeri Aug 28 '21 at 13:55
  • A list of size `0` could indicate that the stubbing setup for your `orderService` is not correct and hence Mockito falls back to the default return value which is an empty list for `List>`. Are you using the argument matches `anyString()` from Mockito or accidently from a different library? Can you share the entire import section of your test? – rieckpil Oct 16 '21 at 08:14

0 Answers0