使用 Junit 和 Mockito 的 Rest API 的 Junit 测试用例

Junit test cases for Rest API using Junit and Mockito

API 的 Junit 测试用例 我是 Junit 和 Mockito 的新手,试图为我的控制器 class 编写单元测试用例来测试我的 API。 这里是控制器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";
    }
}

我试过以下方法 添加 @ExtendWith(MockitoExtension.class) 并尝试但仍然失败

 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);
    }
}

测试用例testGetProductDetails()失败,不知道是不是map的原因?

为了能够使用(@Mock@InjectMocks)将模拟注入应用程序上下文并使其可供您使用 MockMvc,您可以尝试初始化 MockMvc 在独立模式下启用了唯一的 ProductController 个实例(您刚刚模拟的那个)。

示例:

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);
    }

}