Mockito筆記

maven配置

// spring boot這裏用的是2.1.5.RELEASE版本
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
 </dependency>
 或者
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

例子

簡單入門

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.HashMap;
import java.util.Map;

import static org.mockito.Mockito.*;

public class MockitoTest {

    static class A{
        private String name = "test";
    }

    @Test
    public void testReturn(){
        Map map = Mockito.mock(HashMap.class);
        A a = new A();
        Mockito.when(map.get("a")).thenReturn(a);
        Assert.assertEquals(((A)map.get("a")).name, a.name);
        a.name = "next";
        Assert.assertEquals(((A)map.get("a")).name, a.name);
    }

    @Test
    public void testMockMap() {
        Map map = Mockito.mock(HashMap.class);
        // 校驗:類型
        Assert.assertTrue(map instanceof Map);
        Assert.assertTrue(map instanceof HashMap);

        // 校驗:when().thenReturn();
        Assert.assertEquals(map.put(1, 1), null);
        when(map.put(1, 1)).thenReturn(true);
        Assert.assertTrue((Boolean) map.put(1, 1));

        Assert.assertEquals(map.get(1), null);
        when(map.get(1)).thenReturn(1);
        Assert.assertEquals(map.get(1), 1);

        Assert.assertEquals(map.size(), 0);
        when(map.size()).thenReturn(10);
        Assert.assertEquals(map.size(), 10);

        // 校驗:拋出異常類型,僅針對get(1)拋出,而get(2)不會
        doThrow(new NullPointerException()).when(map).get(1);
        Assert.assertThrows(NullPointerException.class, () -> map.get(1));
        map.get(2);

        // 校驗調用次數
        map.putAll(new HashMap());
        verify(map, times(1)).putAll(new HashMap());
        Map map1 = new HashMap();
        map1.put(1, 3);
        map.putAll(map1);
        map.putAll(map1);
        verify(map, times(2)).putAll(map1);
        verify(map, times(2)).putAll(map1);
    }

    /**
     * 部分模擬
     */
    @Test
    public void testPart() {
        Map old = new HashMap();
        Map map = spy(old);
        Assert.assertTrue(map instanceof Map);
        Assert.assertTrue(map instanceof HashMap);

        map.put(1, 1);
        // 下面不需要when().thenReturn就可以拿到數據
        Assert.assertEquals(map.get(1), 1);
        Assert.assertEquals(map.size(), 1);

        // doNothing().when(map).putAll(map1)
        Map map1 = new HashMap();
        map1.put(1, 3);

        map.clear();
        map.putAll(map1);
        Assert.assertEquals(map.get(1), 3);

        doNothing().when(map).putAll(map1);

        map.clear();
        map.putAll(map1);
        Assert.assertEquals(map.get(1), null);

        Map map2 = new HashMap();
        map2.put(3, 3);
        map.putAll(map2);
        Assert.assertEquals(map.get(3), 3);

        // when().thenThrow().thenReturn: 第一次拋出錯誤,第二次返回null...
        Mockito.when(map.get(3)).thenThrow(new RuntimeException()).thenReturn(null, 6);
        Assert.assertThrows(RuntimeException.class, () -> map.get(3));
        Assert.assertEquals(map.get(3), null);
        Assert.assertEquals(map.get(3), 6);
        Assert.assertEquals(map.get(3), 6);
        Assert.assertEquals(map.get(3), 6);
        Assert.assertEquals(map.get(3), 6);

        // 多個then是拆開來寫,不一定對。thenReturn可以換到thenReturn或者thenThrow
        Mockito.when(map.get(3)).thenThrow(new RuntimeException());
        Assert.assertThrows(RuntimeException.class, () -> map.get(3));
        Assert.assertThrows(RuntimeException.class, () -> Mockito.when(map.get(3)).thenReturn(null));
        Assert.assertThrows(RuntimeException.class, () -> Mockito.when(map.get(3)).thenReturn(6));

        Mockito.when(map.get(4)).thenReturn(null);
        Assert.assertEquals(map.get(4), null);
        Mockito.when(map.get(4)).thenReturn(5);
        Assert.assertEquals(map.get(4), 5);
        Mockito.when(map.get(4)).thenThrow(new RuntimeException());
        Assert.assertThrows(RuntimeException.class, () -> map.get(3));

        // any()
        map.clear();
        map.put(10, 10);
        map.put(11, 11);
        Mockito.when(map.get(11)).thenReturn(12);
        Assert.assertEquals(map.get(10), 10);
        Assert.assertEquals(map.get(11), 12);
        Mockito.when(map.get(Mockito.any())).thenReturn(13);
        Assert.assertEquals(map.get(10), 13);
        Assert.assertEquals(map.get(11), 13);
    }
}

http請求

BaseTest.java\Result.java
package com.ydfind.start;

import com.ydfind.start.common.response.Result;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = MainApplication.class)
@RunWith(SpringRunner.class)
public abstract class BaseTest {

    protected void assertSuccess(Result<?> result) {
        Assert.assertEquals(Result.SUCCESS, result.getCode());
    }

    protected void assertFail(Result<?> result) {
        Assert.assertEquals(Result.ERROR, result.getCode());
    }

    protected <T> void assertSuccess(Result<T> result, T targetData) {
        Assert.assertEquals(Result.SUCCESS, result.getCode());
        Assert.assertEquals(result.getData(), targetData);
    }

    protected <T> void assertFail(Result<T> result, String targetMsg) {
        Assert.assertEquals(Result.ERROR, result.getCode());
        Assert.assertEquals(result.getMsg(), targetMsg);
    }
}
package com.ydfind.start.common.response;

import lombok.Data;
import java.io.Serializable;

@Data
public class Result<T> implements Serializable {
    public static String SUCCESS = "200";
    public static String ERROR = "500";

    private T data;
    private String code;
    private String msg;

    public Result(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static <T> Result<T> success(String msg, T data) {
        return new Result<>(SUCCESS, msg, data);
    }

    public static <T> Result<T> error(String msg, T data) {
        return new Result<>(ERROR, msg, data);
    }
}
controller
@Autowired
    MyMockService myMockService;

    @Autowired
    MyMockService myMockService1;

    @GetMapping("/name")
    @ApiOperation("獲取名稱")
    @ApiImplicitParam(name = "id", value = "主鍵id", defaultValue = "0")
    public Result<String> getName(String id) {
        return Result.success(null, myMockService.getName(id));
    }

    @PostMapping("/name")
    @ApiOperation("獲取名稱")
    @ApiImplicitParam(name = "id", value = "主鍵id", defaultValue = "0")
    public Result<String> postName(String id) {
        return Result.success(null, "post:" + myMockService1.getName(id));
    }

    @PostMapping("/name1")
    @ApiOperation("獲取名稱")
    @ApiImplicitParam(name = "requestDto", value = "請求對象", defaultValue = "null")
    public Result<String> postName1(@RequestBody UserRequestDto requestDto) {
        return Result.success(null, "post:" + JSON.toJSONString(requestDto));
    }

    @GetMapping("/name1")
    @ApiOperation("獲取名稱")
    @ApiImplicitParam(name = "id", value = "主鍵id", defaultValue = "0")
    public Result<String> getName1(String id) {
        return Result.success(null, myMockService1.getName(id));
    }

    @GetMapping("/list")
    @ApiOperation("獲取列表")
    public Result<List<UserRequestDto>> getList() {
        List<UserRequestDto> list = new ArrayList<>();
        UserRequestDto item = new UserRequestDto();
        item.setId(1);
        item.setName("1");
        item.setAge(1);
        UserRequestDto item1 = new UserRequestDto();
        item1.setId(2);
        item1.setName("2");
        item1.setAge(2);
        list.add(item);
        list.add(item1);
        return Result.success(null, list);
    }
ControllerTest.java
package com.ydfind.start.controller.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ydfind.start.BaseTest;
import com.ydfind.start.common.response.Result;
import com.ydfind.start.controller.test.model.UserRequestDto;
import com.ydfind.start.service.test.MyMockService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

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

public class ControllerTest extends BaseTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @MockBean
    private MyMockService myMockService;

    @Before
    public void init() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void testGet() throws Exception {
        String returnString = "this is mockito name.";
        Mockito.doReturn(returnString).when(myMockService).getName(Mockito.anyString());
        String resultStr = mockMvc.perform(MockMvcRequestBuilders.get("/mock/name")
                .param("id", "user")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        Result<String> result = JSONObject.parseObject(resultStr, Result.class);
        assertSuccess(result, returnString);
    }

    @Test
    public void testPost() throws Exception {
        String returnString = "this is mockito name.";
        Mockito.doReturn(returnString).when(myMockService).getName(Mockito.anyString());
        String resultStr = mockMvc.perform(MockMvcRequestBuilders.post("/mock/name")
                .param("id", "user")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        Result<String> result = JSONObject.parseObject(resultStr, Result.class);
        assertSuccess(result, "post:" + returnString);
    }

    @Test
    public void testPost1() throws Exception {
        String returnString = "this is mockito name.";
        Mockito.doReturn(returnString).when(myMockService).getName(Mockito.anyString());
        UserRequestDto requestDto = new UserRequestDto();
        requestDto.setAge(18);
        requestDto.setId(1);
        requestDto.setName("user");
        String resultStr = mockMvc.perform(MockMvcRequestBuilders.post("/mock/name1")
                .content(JSON.toJSONString(requestDto))
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        Result<String> result = JSONObject.parseObject(resultStr, Result.class);
        assertSuccess(result, "post:" + JSON.toJSONString(requestDto));
    }

    @Test
    public void testGetList() throws Exception {
        String resultStr = mockMvc.perform(MockMvcRequestBuilders.get("/mock/list")
                .param("id", "user")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        Result<List<UserRequestDto>> result = JSONObject.parseObject(resultStr,
                new TypeReference<Result<List<UserRequestDto>>>(){});
        Assert.assertTrue(result.getData() instanceof ArrayList);
        Assert.assertEquals(result.getData().size(), 2);
    }
}

常見使用

  • @MockBean。
@MockBean
XxxService xxxService;
  • Mockito.doReturn.when(對象).該對象或接口函數(any()…)
  • any()。任意T
  • RestTemplate請求進行mock
private RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
Mockito.deReturn(返回對象).when(restTemplate).exchange(anyString(), eq(HttpMethod.GET), any(), any(ParameterizedTypeReference.class);
  • Mockito.doReturn().when().、Mockito.when().thenReturn()。thenReturn對於Mockito.spy對象來說會先執行,再返回。
  • Mockito.verify(xxxService).method(ArgumentCaptor param);System.out.println(param.getValue)。攔截調用的參數值。

Spring boot中應用

controller

@MockBean
XxxService xxxService;
@Autowire
XxxController xxxController;
// 對service進行mock,controller中進行驗證
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章