Mockito测试封装

Mockito测试基类

在开发中,经常需要写测试用例,来测试业务或者服务是否正常,一般会用到M ockito测试框架进行编写Controller和ServiceImpl的测试代码。

首先加入依赖:

<!-- spring boot 中包含 Mockito -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

Controller测试用例基类

/**
 * Controller Parent
 *
 * @author liwenqiang 2018/12/28 14:40
 **/
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public abstract class BasicControllerMock<T> {

    private MockMvc mockMvc;

    protected abstract T getController();

    public MockMvc getMockMvc() {
        return mockMvc;
    }

    @Before
    public void setupMock() {
        /* initialize mock object */
        this.mockMvc = MockMvcBuilders.standaloneSetup(this.getController()).build();
        MockitoAnnotations.initMocks(this);
    }

    /* ====================  POST 重载 添加参数到request body ====================*/
    public MockHttpServletResponse postTest(String url, Object obj) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post(url).accept(MediaType.APPLICATION_JSON_UTF8)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(obj)));
        return resultActions.andReturn().getResponse();
    }

    /* ====================  POST 重载 添加Map类型参数到请求中 ====================*/
    public MockHttpServletResponse postTest(String url, MultiValueMap<String, String> params) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.post(url).params(params).accept(MediaType.APPLICATION_JSON_UTF8)
                .contentType(MediaType.APPLICATION_JSON_UTF8));
        return resultActions.andReturn().getResponse();
    }

    /* ====================  GET 重载 添加参数到request body ====================*/
    public MockHttpServletResponse getTest(String url, Object obj) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.get(url).accept(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(obj)));
        return resultActions.andReturn().getResponse();
    }

    /* ====================  GET 重载 添加Map类型参数到请求中 ====================*/
    public MockHttpServletResponse getTest(String url, MultiValueMap<String, String> params) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.get(url).params(params).accept(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                .contentType(MediaType.APPLICATION_JSON_UTF8));
        return resultActions.andReturn().getResponse();
    }

    /* ====================  PUT  ====================*/
    public MockHttpServletResponse putTest(String url, Object obj) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.put(url).accept(MediaType.APPLICATION_JSON_UTF8)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(obj)));
        return resultActions.andReturn().getResponse();
    }

    /* ====================  DELETE  ====================*/
    public MockHttpServletResponse deleteTest(String url, Object obj) throws Exception {
        ResultActions resultActions = mockMvc.perform(MockMvcRequestBuilders.delete(url).accept(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                .contentType(MediaType.APPLICATION_JSON_UTF8).content(new ObjectMapper().writeValueAsString(obj)));
        return resultActions.andReturn().getResponse();
    }
}

Controller 测试使用示例:

/**
 * java类描述
 *
 * @author liwenqiang 2019/1/29 17:09
 **/
public class UserInfoControllerTest extends BasicControllerMock<UserInfoController> {

    @Mock
    private UserInfoServiceImpl userInfoService;

    @InjectMocks
    private UserInfoController userInfoController;

    @Override
    protected UserInfoController getController() {
        return userInfoController;
    }

    @Test
    public void findUsers() throws Exception {
        MultiValueMap<String, String> pageMap = new LinkedMultiValueMap<>();
        pageMap.add("curPage", "1");
        pageMap.add("pageSize", "10");
        Mockito.when(userInfoService.findAllByPage(Mockito.anyInt(), Mockito.anyInt())).thenReturn(Page.empty());
        MockHttpServletResponse response = super.getTest("/users", pageMap);
        //验证测试结果
        Assert.assertThat(response.getStatus(), Matchers.equalTo(HttpStatus.OK.value()));
    }

    @Test
    public void saveUser() throws Exception {
        MockHttpServletResponse response = super.postTest("/user", Mockito.any(UserInfoModel.class));
        Mockito.verify(userInfoService, Mockito.times(1)).save(Mockito.any(UserInfoModel.class));
        //验证测试结果
        Assert.assertThat(response.getStatus(), Matchers.equalTo(HttpStatus.CREATED.value()));
    }
}

ServiceImpl 测试用例基类

测试serviceImpl方法,其实很简单,没有特别的需要配置,只用一个简单的MockitoJUnitRunner.class就可以了,甚至连SpringbootTest注解都不用。

/**
 * ServiceTest Basic Class
 *
 * @author liwenqiang 2018/12/28 14:40
 **/
@RunWith(MockitoJUnitRunner.class)
public abstract class BasicServiceMock {

}

ServiceImpl 测试使用示例:

/**
 * java类描述
 *
 * @author liwenqiang 2019/1/29 17:10
 **/
public class UserInfoServiceImplTest extends BasicServiceMock {

    @Mock
    private UserInfoDao userInfoDao;

    @InjectMocks
    private UserInfoServiceImpl userInfoService;

    @Test
    public void save() {
        UserInfoModel user = new UserInfoModel();
        user.setId(0L);
        user.setUserNameCn("管理员");
        userInfoService.save(user);
        Mockito.verify(userInfoDao, Mockito.times(1)).save(user);
    }

    @Test
    public void getById() {
        UserInfoModel user = new UserInfoModel();
        user.setId(0L);
        Mockito.when(userInfoDao.findById(Mockito.anyLong())).thenReturn(Optional.of(user));
        UserInfoModel userInfo = userInfoService.getById(user.getId());
        Assert.assertThat(userInfo.getId(), Matchers.equalTo(0L));
    }

}

VO测试基类

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * VO Test Parent
 *
 * @author liwenqiang 2018/12/28 14:40
 **/
@RunWith(MockitoJUnitRunner.class)
public abstract class BasicVOMock<T> {

    protected abstract T setVO();

    @Before
    public void setupMock() {
        MockitoAnnotations.initMocks(this);
    }

    /**
     * model的get和set方法
     */
    public void testGetAndSet() throws IllegalAccessException, InstantiationException, IntrospectionException,
            InvocationTargetException {
        T t = setVO();
        Class modelClass = t.getClass();
        Object obj = modelClass.newInstance();
        Field[] fields = modelClass.getDeclaredFields();
        for (Field f : fields) {
            PropertyDescriptor pd = new PropertyDescriptor(f.getName(), modelClass);
            Method get = pd.getReadMethod();
            Method set = pd.getWriteMethod();
            set.invoke(obj, get.invoke(obj));
        }
    }

    @Test
    public void getAndSetTest() throws InvocationTargetException, IntrospectionException,
            InstantiationException, IllegalAccessException {
        this.testGetAndSet();
    }

}

VO测试使用示例:

/**
 * UserInfoVO Test
 *
 * @author liwenqiang 2019/1/29 17:33
 **/
public class UserInfoVOTest extends BasicVOMock<UserInfoVO> {

    @Override
    protected UserInfoVO setVO() {
        return new UserInfoVO();
    }
}
Technology 12/14/2021, 4:56:41 PM
554
0
0
testMockitomvc
如有帮助,点赞鼓励一下吧!