单元测试mock

最近认真的写了一下单元测试,当然由于项目需要。。。要不然,嗯,给我钱我也不愿意做这么恶心的事情,还不如去看看小电影。。。

我在项目里由于单元测试要求覆盖率较高,所以在提高覆盖率的时候碰到了一个难题。。。啥难题??就是静态方法的测试,,比如你封装了一个http请求的客户端。。比如各种工具类。。如果按照真实的数据去测试是不是很恶心。。但是我突然不会静态方法的mock了。。上网也看了好多资料感觉说的都有些偏差,在这我就简单的把我经历的跟小伙伴了分享下。。

原来(springboot)项目导入的依赖包:


    org.mockito
    mockito-all
    1.10.19
    test

在controller层测试时需要这样写:

package com.zy.mocktest.controller;

import com.github.pagehelper.PageInfo;
import com.zy.mocktest.model.MockTestModel;
import com.zy.mocktest.service.IMockTestService;
import com.zy.mocktest.util.RequestParamsUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
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.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
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 javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RunWith(SpringRunner.class)
public class MockTestControllerTest {

    private MockMvc mvc;
    
    @InjectMocks
    private MockTestController mockTestController;
    @Mock
    private IMockTestService mockTestService;
    @Mock
    private HttpServletRequest request;

    @Before
    public void before() {
        mvc = MockMvcBuilders.standaloneSetup(mockTestController).build();
//        PowerMockito.mockStatic(RequestParamsUtil.class);
    }

    @Test
    public void search() throws Exception {
        Map paramMap = new HashMap<>();
        paramMap.put("orderType", "DESC");
//        PowerMockito.when(RequestParamsUtil.getParamsMap(Mockito.any())).thenReturn(paramMap);
        Mockito.when(mockTestService.searchMockTestModel(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(new PageInfo());
        mvc.perform(MockMvcRequestBuilders.post("/mock/search").contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param("orderType", "DESC")).andExpect(MockMvcResultMatchers.status().isOk());

    }
}

 

但是以上的写法不能测试mock静态方法,

需要改成下面的依赖:


    org.mockito
    mockito-core
    1.10.19
    test



    org.powermock
    powermock-api-mockito
    1.6.5
    test


    org.powermock
    powermock-module-junit4
    1.6.5
    test

然后controller层的测试这样写:

package com.zy.mocktest.controller;

import com.github.pagehelper.PageInfo;
import com.zy.mocktest.model.MockTestModel;
import com.zy.mocktest.service.IMockTestService;
import com.zy.mocktest.util.RequestParamsUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
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.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
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 javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RunWith(PowerMockRunner.class)
@PrepareForTest(RequestParamsUtil.class)
public class MockTestControllerTest {

    private MockMvc mvc;

    @InjectMocks
    private MockTestController mockTestController;
    @Mock
    private IMockTestService mockTestService;
    @Mock
    private HttpServletRequest request;

    @Before
    public void before() {
        mvc = MockMvcBuilders.standaloneSetup(mockTestController).build();
        PowerMockito.mockStatic(RequestParamsUtil.class);
    }

    @Test
    public void search() throws Exception {
        Map paramMap = new HashMap<>();
        paramMap.put("orderType", "DESC");
        PowerMockito.when(RequestParamsUtil.getParamsMap(Mockito.any())).thenReturn(paramMap);
        Mockito.when(mockTestService.searchMockTestModel(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(new PageInfo());
        mvc.perform(MockMvcRequestBuilders.post("/mock/search").contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param("orderType", "DESC")).andExpect(MockMvcResultMatchers.status().isOk());

    }
}

 

这样呢就完美解决了mock静态方法的问题同时还可mock service层。

在这里多说几句,有时小伙伴们会想 那我再service层mock dao层跟静态方法时怎样写呢?

第一种情况:在service层mock dao层时 如果 没有静态方法,那么只用mockito.all的依赖,只能使用@MockBean来注入dao层,因为dao层为接口不能被实例化

第二种情况:在service层mock dao层时 有静态方法,依赖powermock的时候,那么就直接使用@Mock来注入dao层

就给大家说这么多了,,,困了,如果大家在写测试时遇到什么问题可以再来跟我交流····,最后动动您老的小指头点个赞吧!!!

 

你可能感兴趣的:(java单元测试,单元测试)