Mockito使用记录

临时出一版,结构不是很清晰,记录一下。

1,为返回值为void的函数通过Stub抛出异常

我发现要在这句异常抛出声明之后调用才会抛出异常:

doThrow(new RuntimeException()).when(mockService).selectUserById(anyLong());

比如我这段代码,声明之前也有调用方法,但是没有抛出异常,在后边又调用一次才抛出:
在这里插入图片描述

2,verify

然后研究的时候呢,一直不明白官网上给的那些基础用例什么时候用的到,后来研究了nacos的源码,慢慢理解了,比如这个

verify(ephemeralConsistencyService).put(ephemeralKey, record);

之前不明白为啥还要验证某个函数是否执行以及执行了几次呢。那nacos里是这样用的:
在这里插入图片描述
(1)那里,传的是ephemeralKey,期望执行ephemeralConsistencyService的put方法,而persistentConsistencyService的put方法就要never执行
(2)那里,传的peristentKey,期望persistentConsistencyService的put方法执行。
内部代码是这样:

private ConsistencyService mapConsistencyService(String key) {
        return KeyBuilder.matchEphemeralKey(key) ? ephemeralConsistencyService : persistentConsistencyService;
    }

根据传入的不同参数调用不同的servic里的put方法,那这里就是要验证delegateConsistencyService的put方法内部是不是这样执行的。

还有验证controller的就比如下边这个:
在这里插入图片描述
在这里插入图片描述
HealthController里的readiness方法就需要两个方法调用的结果喽

 boolean isConfigReadiness = isConfigReadiness();
        boolean isNamingReadiness = isNamingReadiness(request);

那截图中
(1)那里就构造两个正常的返回结果,然后HealthController里的readiness方法就返回正常相应码和响应信息;
(2)那里就让persistService.configInfoCount和apiCommands.metrics抛出异常,
HealthController里的readiness的方法验证时候就返回500响应码和异常信息:Config and Naming are not in readiness
(3)那里就只让persistService.configInfoCount抛出异常,
HealthController里的readiness的方法验证时候就返回500响应码和异常信息:Config is not in readiness

这个应该是验证controller层执行结果是否与预期相同的

3,测试controller中某个方法的返回值,方法中需要调用service层的某个方法,使用mock模拟这个service返回值:
 @RequestMapping("/findUserById")
    public SysUser findUserById() {
        SysUser user = userService.selectUserById(new Long(102));
        return user;
    }
package com.ruoyi.system;

import com.alibaba.nacos.client.config.impl.SpasAdapter;
import com.ruoyi.system.controller.SysUserController;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
import org.junit.Assert;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
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.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
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;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
public class UserControllerTest {

    @InjectMocks
    private SysUserController sysUserController;

    private MockMvc mockMvc;

    @Mock
    private ISysUserService userService;


    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(sysUserController).build();
//        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }


    @Test
    public void testGetUsrList() throws Exception {
        String url = "/user/hello";
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(url).param("name","Tom");
        mockMvc.perform(builder).andExpect(MockMvcResultMatchers.content().string("Hello Tom!"));


    }

    @Test
    public void testFindUserById() throws Exception {
        SysUser user = new SysUser();
        user.setNickName("alibaba");
        Mockito.when(userService.selectUserById(any(Long.class))).thenReturn(user);
        String url = "/user/findById";
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(url);
//        Assert.assertEquals(200, mockMvc.perform(builder).andReturn().getResponse().getStatus());
        Assert.assertNotNull(mockMvc.perform(builder).andReturn().getResponse().getStatus());
    }

    @Test
    public void testFindById() throws Exception {
        SysUser user = new SysUser();
        user.setNickName("alibaba");
        Mockito.when(userService.selectUserById(any(Long.class))).thenReturn(user);
        String url = "/user/findById";
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(url);
        mockMvc.perform(builder).andDo(MockMvcResultHandlers.print());
    }
}

test中,@InjectMocks private SysUserController sysUserController;
的@InjectMocks很重要,如果不写,就无效。

4,测试service层的某个方法,方法中的dao层数据使用mock模拟
package com.ruoyi.system;

import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;

import static org.mockito.Mockito.when;

//@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class UserServiceImplServiceTest {

    @InjectMocks
    private SysUserServiceImpl sysUserService;

    @Mock
    private SysUserMapper sysUserMapper;

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

    @Test
    void testGetById() {
        SysUser user = new SysUser();
        user.setNickName("alibaba");
        when(sysUserMapper.selectUserById(new Long(102))).thenReturn(user);
//        System.out.println(sysUserService.setUserName(null).getNickName());
        Assert.assertEquals("alibaba",sysUserService.setUserName(null).getNickName());
    }

	@Test
    public void testMatcher() {
        SysUser param = new SysUser();
        param.setNickName("haliluya");

        SysUser result = new SysUser();
        result.setNickName("nanamimihong");
        when(sysUserOfMineService.selectUserByUser(argThat(new ArgumentMatcher<SysUser>() {
            @Override
            public boolean matches(SysUser user) {
                return user.getNickName().equals("haliluya");
            }
        }))).thenReturn(result);
        Assert.assertEquals("nanamimihong",sysUserService.setUserName(param).getNickName());
    }

	@Test
    public void testMatcher3() {
        SysUser param = new SysUser();
        param.setUserName("haliluya");
        param.setUserId(new Long(103));

        SysUser result = new SysUser();
        result.setNickName("nanamimihong");

        when(sysUserOfMineService.selectUserByNameAndId(eq("haliluya"), anyLong())).thenReturn(result);
        Assert.assertEquals("nanamimihong",sysUserService.findByName(param).getNickName());
    }

}

@InjectMocks最开始加给了service接口,而不是实现类,但是报错:

org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'testServiceC1'! Cause: the type 'TestServiceC1' is an interface.
You haven't provided the instance at field declaration so I tried to construct the instance.

于是把接口改成了实现类,测试成功了。

testMatcher() 方法是使用自定义参数匹配进行测试,

testMatcher3()方法中, when(sysUserOfMineService.selectUserByNameAndId(eq(“haliluya”), anyLong())).thenReturn(result);第二个参数使用了参数匹配,第一个也需要使用参数匹配,而不能直接用
when(sysUserOfMineService.selectUserByNameAndId(“haliluya”, anyLong())).thenReturn(result);

遇到问题

1,测试controller时候,当用@RequestBody传递参数的时候,一直报400错误,参考文章Junit测试Controller(MockMVC使用),传输@RequestBody数据解决办法说这样解决:

String requestJson = JSONObject.toJSONString(folderInfo);
        String responseString = mockMvc.perform( post("/softs").contentType(MediaType.APPLICATION_JSON).content(requestJson)).andDo(print())
                .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); 

注意是org.springframework.http下的MediaType,我开始引入错误,就说没有这个类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值