java的单元测试-mock测试

文章目录

  • 简介
  • Assert
  • mockMVC
    • 优化
  • mockBean(模拟bean和测试接口)

简介

对于普通的方法,通常采用断言测试。
对于接口,需要使用mockMvc
对于未开发的功能,需要mockBean模拟一个业务bean

Assert

java自身携带的工具类,也可以用于一些对抛出异常要求不高的业务或者存在全局异常的项目

Assert.notNull(in,"入参不存在");

另外有一个更加简单的写法,以assert开头

assert method != null;

mockMVC

曾使用注入方式得到mockMvc,类加上@WebMvcTest注解,实际测试发现这样回影响service bean的注入。

@Slf4j
@SpringBootTest
public class MvcTest {
    private MockMvc mockMvc;
    @Autowired
    protected WebApplicationContext wac;

    @SneakyThrows
    @Test
    void testGetOne(){
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        TestGeOne in = new TestGeOne();
        in.setId(1);
        JSONObject jsonObject = new JSONObject();
        mockMvc.perform(MockMvcRequestBuilders.post("/test/getOne").content(JSON.toJSONBytes(in)).contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpectAll(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON),
                        MockMvcResultMatchers.jsonPath("$.data.id",Is.is(1)),
                        MockMvcResultMatchers.jsonPath("$.data.name").isString())
                .andDo(MockMvcResultHandlers.print());
    }
}

优化

添加BeforeEach注解,用于每次初始化mock

    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;

    @MockBean
    private TestServcie testServcie;

    //在每个测试方法执行之前都初始化MockMvc对象
    @BeforeEach
    public void setupMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

mockBean(模拟bean和测试接口)

关键引用import static org.mockito.Mockito.*;
否则使用Mockito.when
另外就是在接口或者实现方法上加MockBean,这里注解可以放接口也可以具体的实现service。

注意mock(TestGetOneRes.class);实际测试中存在问题

@Slf4j
@SpringBootTest
public class MockBeanTest {
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;

    @MockBean
    private TestServcie testServcie;

    //在每个测试方法执行之前都初始化MockMvc对象
    @BeforeEach
    public void setupMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        TestGetOneRes testGetOneRes = new TestGetOneRes();
        testGetOneRes.setId(1);
        testGetOneRes.setName("mock 测试");
        //静态导入import static org.mockito.Mockito.*;才能使用when方法
        when(testServcie.getOne(1)).thenReturn(testGetOneRes);
        //另一种写法
        TestGetOneRes testGetOneRes2 = new TestGetOneRes();
        testGetOneRes2.setId(2);
        doReturn(testGetOneRes2).when(testServcie).getOne(2);
    }

    @SneakyThrows
    @Test
    void testGetOne(){
        TestGeOne in = new TestGeOne();
        in.setId(1);
        Assert.notNull(in,"入参不存在");
        mockMvc.perform(MockMvcRequestBuilders.post("/test/getOne").content(JSON.toJSONBytes(in)).contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpectAll(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON),
                        MockMvcResultMatchers.jsonPath("$.data.id", Is.is(1)),
                        MockMvcResultMatchers.jsonPath("$.data.name").isString())
                .andDo(MockMvcResultHandlers.print());
    }

}

当出现多个mock都符合条件的时候,一般是最后一条mock生效。
但是如果中间出现抛异常,就直接返回了

        //入参等于某个值
        Mockito.when(testServcie.getOne(Mockito.eq(1))).thenReturn(testGetOneRes);
        //任意值
        Mockito.when(testServcie.getOne(Mockito.any())).thenReturn(testGetOneRes);
        //抛异常
        Mockito.when(testServcie.getOne(Mockito.isNotNull())).thenThrow(MyException.class);
        //自定义
        Mockito.when(testServcie.getOne(Mockito.anyInt())).thenAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                Method method = invocationOnMock.getMethod();
                Object[] arguments = invocationOnMock.getArguments();
                //这里是因为只有一个入参,所以就直接使用第一参数
                Integer id = (Integer)arguments[0];
                TestGetOneRes testGetOneRes = new TestGetOneRes();
                testGetOneRes.setId(id);
                testGetOneRes.setName(id + ":" + new Date().toString());
                return testGetOneRes;
            }
        });

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