欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中的单元测试

程序员文章站 2022-06-05 09:28:56
...

java中的单元测试

单元测试(unit testing),是指对软件中最小可测试单元进行检查和验证。单元测试是软件质量最简单有效的保证,是目标代码最清晰有效的文档,是代码重构的保障,是回归测试和持续集成的基石,可以优化目标代码的设计。

junit

JUnit4通过注解的方式来识别测试方法。

常用注解(按执行顺序排序)

  • @BeforeClass :针对所有测试,也就是整个测试类中,在所有测试方法执行前,都会先执行由它注解的方法,而且只执行一次。当然,需要注意的是,修饰符必须是 public static void xxxx ;此 Annotation 是 JUnit 4 新增的功能。
  • @Before :初始化方法,任何一个测试方法执行之前执行的代码,可以初始化对象,打开网络连接等
  • @Test :测试方法,不能带参数,public void,私有方法没必要测试
  • @After: 测试方法执行后的收尾工作,比如释放资源
  • @AfterClass: 针对所有测试,也就是整个测试类中,在所有测试方法都执行完之后,才会执行由它注解的方法,而且只执行一次。当然,需要注意的是,修饰符也必须是 public static void xxxx ;此 Annotation 也是 JUnit 4 新增的功能,与 @BeforeClass 是一对。
  • @Ignore :表示该方法还没写完,先不测他。测试时会跳过它,这样少测这个类最后也是绿色的通过

测试规范

  • 单元测试代码应该位于单独的source folder下,通常为test下
  • 测试类与被测试类应位于同一package下
  • 测试方法名最好有意义,test<待测方法名>[概要描述]
  • 每项单元测试必须独立于其他单元测试
  • 为暂未实现的方法添加@Ignore
  • 用断言时使用带参数的断言,给出失败原因。assertEquals(String msg,Object expected,Object actual), assertTrue(String msg,boolean condition), assertNull/NotNull(String msg,Object object)

mock

测试时经常用到很多外部对象(service,dao,发送邮件,网络通信,日志,文件系统等),可以用mock来模拟这些对象。

spring中使用单元测试

以前版本

  • @RunWith(SpringJUnit4ClassRunner.class)
  • @WebAppConfiguration(value=“src/main/webapp”)
  • @ContextConfiguration(classes=SpringConfig.class, SpringMvcConfig.class)

现在版本

  • @RunWith(SpringRunner.class) 指定运行于基于junit的spring测试环境
  • @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
  • @AutoConfigureMockMvc 自动配置一个模拟的mvc,可以发请求,测controller时需要这个,测service只需要直接注入一个service即可。这时候可以@Autowired一个MockMvc
  • 如果要自己注入mockmvc,有两种方式,一种是独立测试,先注入一个controller,然后mockMvc=MockMvcBuilders.standaloneSetup(userController).build()模拟一个mvc测试环境。第二种是集成web环境,先注入一个WebApplicationContext wac,然后mockMvc=MockMvcBuilders.webAppContextSetup(wac).build()
  • @ContextConfiguration(classes=SpringConfig.class, SpringMvcConfig.class) 如果需要指定配置文件或类
  • @RestClientTest
  • @Transactional 如果需要测试dao层,开启事务
  • @TransacitonalConfiguration

MockMvc的基本操作

  • MockMvcBuilder.build()构建一个mockMvc

  • mockMvc.perform() 执行一个请求,返回ResultActions

  • MockMvcRequestBuilders.get("/user/1") 构建一个请求,还有put,delete,options方法,后面可以带Object… uriVars这个是地址参数,可以在前面的url中用{uriVarName}来引用。

    • 该请求可以连点,设置其他参数。普通参数则用.param()或.params()来添加
    • contentType(MediaType.APPLICATION_JSON)指定媒体类型
    • content()可以设置requesBody,通常用来加json参数
    • accept(MediaType.APPLICATION_JSON),指定客户端接收的内容类型
  • ResultActions可以有三种处理

    • andExpect(ResultMatcher matcher) 添加执行后的断言,判断是否符合预期
    • andDo(ResultHandler handler) 添加结果处理器,对于验证成功后执行的动作,如输出结果用于调试
    • andReturn() 验证成功后返回一个MvcResult,用于自定义验证或其他异步处理
  • ResultMatcher 断言的种类相当多,这里只列出常见的

    • StatusResultMatchers.status() 该工厂方法的返回值则是ResultMatcher类型。通常断言status().isOk()
    • JsonPathResultMatchers.jsonPath(String exp,Object…args),取出返回数据中某个字段进行验证,其中表达式使用**$.属性** 来获取,如:jsonPath("$.data.name", is(“abc”)) 则取到了data.name这个属性,并进行判断
    • MockMvcResultMatchers.model().attributeExists(“user”) 判断取到的model中含有user这个属性
  • ResultHandler

    MockMvcResultHandlers.print() 输出整个响应结果信息

mockMvc.perform(post("/user")  // 路径
            //用contentType表示具体请求中的媒体类型信息,MediaType.APPLICATION_JSON表示互联网媒体类型的json数据格式
            .contentType(MediaType.APPLICATION_JSON).content(example)
             //accept指定客户端能够接收的内容类型 
            .accept(MediaType.APPLICATION_JSON))
    	//验证响应contentType == application/json;charset=UTF-8
        .andExpect(content().contentType("application/json;charset=UTF-8")) 
    	//验证id是否为1,jsonPath的使用
        .andExpect(jsonPath("$.id").value(1)) 
    	// 验证name是否等于Zhukeqian
        .andExpect(jsonPath("$.name).value("kqzhu");