0

I am unit testing in a spring boot application. But as the getProductById() method returns Optional of the object, I am not sure how to test it.

ProductController.java

@GetMapping("/products/{id}")
@Transactional(readOnly=true)
@Cacheable("product-cache")
public Product getProduct(@PathVariable("id") int id) {
        LOGGER.info("Finding product by id : "+id);
        return productRepository.findById(id).get();
}

MockTest.java

private static final String PRODUCTS_URL = "/productsapi/products";
private static final int PRODUCT_ID = 1;
private static final String CONTEXT_URL = "/productsapi";
private static final int PRODUCT_PRICE = 1000;
private static final String PRODUCT_DESCRIPTION = "Its awesome";
private static final String PRODUCT_NAME = "Macbook";

@Test
public void testGetProductById() throws JsonProcessingException, Exception {
        Product product = buildProduct();
        when(productRepository.findById(PRODUCT_ID)).thenReturn(Optional.of(product));
        
        ObjectWriter objectWriter = new ObjectMapper().writer().withDefaultPrettyPrinter();
        mockMvc.perform(get(PRODUCTS_URL).contextPath(CONTEXT_URL))
           .andExpect(status().isOk())
           .andExpect(content().json(objectWriter.writeValueAsString(Optional.of(product))));
}

private Product buildProduct() {
        Product product = new Product();
        product.setId(PRODUCT_ID);
        product.setName(PRODUCT_NAME);
        product.setDescription(PRODUCT_DESCRIPTION);
        product.setPrice(PRODUCT_PRICE);
        return product;
}

When I run the test, it fails with below error.

Error: java.lang.AssertionError: Expected: a JSON object got: a JSON array

It doesn't show any compilation error. But test case fails. I think it's the problem with conversion of product object into json.

So, little help in resolving this will be helpful!!

1 Answer 1

1

The controller method is only returning Product object which is a JSON {} and in the andExpect method you are asserting with array of JSON [{}], remove the Optional and only pass product object

mockMvc.perform(get(PRODUCTS_URL).contextPath(CONTEXT_URL)).andExpect(status().isOk())
            .andExpect(content().json(objectWriter.writeValueAsString(product)));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.