Home > Enterprise >  Junit test cases for Rest API using Junit and Mockito
Junit test cases for Rest API using Junit and Mockito

Time:06-03

Junit test cases for API's I'm new to Junit and Mockito, trying to write unit test cases for my controller class to test my APIs. Here is the controller class

package com.mylearnings.controller;

import com.mylearnings.modal.Product;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@RestController
public class ProductController {

    private HashMap<String, Product> productCatalog = new HashMap<>();

    @PostMapping("/product")
    public ResponseEntity addProduct(@RequestBody Product product) {
        productCatalog.put(product.getId(), product);
        return new ResponseEntity("product added successfully", HttpStatus.CREATED);
    }

    @GetMapping("/product/{id}")
    public ResponseEntity getProductDetails(@PathVariable String id) {
        return ResponseEntity.ok(productCatalog.get(id));
    }

    @GetMapping("/product")
    public List<Product> getProductList() {
        return new ArrayList<>(productCatalog.values());
    }

    @PutMapping("/product")
    public String updateProduct(@RequestBody Product product) {
        productCatalog.put(product.getId(), product);
        return "product updated successfully";
    }

    @DeleteMapping("/product/{id}")
    public String deleteProduct(@PathVariable String id) {
        productCatalog.remove(id);
        return "product deleted successfully";
    }
}

I have tried the following Added @ExtendWith(MockitoExtension.class) and tried but still it's failing

 package com.mylearnings.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mylearnings.modal.Product;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@SpringBootTest
@AutoConfigureMockMvc
public class ProductControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Mock
    private Map<String, Product> productCatalog;

    @InjectMocks
    private ProductController productController;

    @Test
    public void testAddProduct() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/product").contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(new Product("MS116", "Dell MS116", "Dell MS116 Usb wired optical mouse", "", 229d)))).andReturn();

        assertEquals(201, mvcResult.getResponse().getStatus());
    }

    @Test
    public void testGetProductDetails() throws Exception {
        Product product = new Product("MS116", "Dell MS116", "Dell MS116 Usb wired optical mouse", "", 229d);
        when(productCatalog.get("MS116")).thenReturn(product);
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/product/{id}", "MS116").accept(MediaType.APPLICATION_JSON)).andReturn();

        assertEquals(200, mvcResult.getResponse().getStatus());
        Product result = new ObjectMapper().readValue(mvcResult.getResponse().getContentAsString(), Product.class);
        assertEquals(product, result);
    }
}

the test case testGetProductDetails() is failing, I'm not sure whether it is because of map?

CodePudding user response:

In order to be able to inject mocks into Application context using (@Mock and @InjectMocks) and make it available for you MockMvc, you can try to init MockMvc in the standalone mode with the only ProductController instance enabled (the one that you have just mocked).

Example:

package com.mylearnings.controller;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import com.mylearnings.controller.Product;
import com.mylearnings.controller.ProductController;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@ExtendWith(MockitoExtension.class)
public class ProductControllerTest {

    private MockMvc mockMvc;

    @Mock
    private HashMap<String, Product> productCatalog;

    @InjectMocks
    private ProductController productController;

    @BeforeEach
    public void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(productController)
                .build();
    }

    @Test
    public void testAddProduct() throws Exception {
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/product").contentType(MediaType.APPLICATION_JSON)
                        .content(new ObjectMapper().writeValueAsString(new Product("MS116", "Dell MS116", "Dell MS116 Usb wired optical mouse", "", 229d))))
                .andReturn();

        assertEquals(201, mvcResult.getResponse().getStatus());
    }

    @Test
    public void testGetProductDetails() throws Exception {
        Product product = new Product("MS116", "Dell MS116", "Dell MS116 Usb wired optical mouse", "", 229d);
        when(productCatalog.get("MS116")).thenReturn(product);
        MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/product/{id}", "MS116").accept(MediaType.APPLICATION_JSON)).andReturn();

        assertEquals(200, mvcResult.getResponse().getStatus());
        Product result = new ObjectMapper().readValue(mvcResult.getResponse().getContentAsString(), Product.class);
        assertEquals(product, result);
    }

}
  • Related