教你如何更好的编写JAVA单元测试

如何更好的编写JAVA单元测试

如各位希望转载或引用,请注明出处,尊重原创,谢谢。如有疑问或错误,欢迎邮件沟通。

gitHub地址:https://github.com/thinkingfioa
邮箱地址:thinking_fioa@163.com
博客地址: https://blog.youkuaiyun.com/thinking_fioa
gitHub项目地址:https://github.com/thinkingfioa/tech-summary
gitHub项目代码地址:https://github.com/thinkingfioa/tech-summary-code

本文重点

单元测试覆盖率往往是检验一个系统的可靠性指标,优秀的单元测试能帮助系统提早发现问题。JAVA语言提供了非常好的单元测试框架,本文将重点介绍: 如何编写单元测试Mock+PowerMock使用

1. 背景

开发过程中,很多重要的业务和关键性代码,都需要单元测试覆盖,这样能保证质量。

好的单元测试用例,能有效提高软件的质量,也方便后期的代码重构和维护。但是一般来说编写单元测试工作量很大,单元测试代码维护成本也很高,因为你业务逻辑发生了改变,代码结构发生了改变,不可能不会修改单元测试。

通常单元测试的代码,阅读难度也很高,需要理解具体的业务逻辑。建议编写单元测试时,当需要使用其他类的时候,尽量使用Mock方法,做到单元测试依赖越少,后续修改和理解就更简单。

2. 编写单元测试的原则

2.1 单元测试类包路径管理

建议单元测试中的test包路径目录结构与main包中的目录结构保持一致。

2.2 单元测试类名称管理

建议每个单元测试类测试功能单一,仅针对性测试指定类的方法。比如文件Father.java中类名称为Father,那么我们在test新建一个相同的包结构目录,并在新建后的目录下新建FatherTest.java文件,类名为FatherTest。

单元测试中每个测试方法以testXXX()开头

Father.java
package org.thinking.fioa;

public class Father {
  
  public void growUp() throws Exception {
    
  }
}
FatherTest.java
package org.thinking.fioa;

public class FatherTest {
  
  public void testGrowUp() throws Exception {
    
  }
}

3. POM依赖

JAVA语言下单元测试比不可少三个依赖包,需要配置到pom.xml下。powermock + mockito + junit。

<!-- unit -->
   <dependency>
     <groupId>org.powermock</groupId>
     <artifactId>powermock-module-junit4</artifactId>
     <version>2.0.2</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.powermock</groupId>
     <artifactId>powermock-api-mockito2</artifactId>
     <version>2.0.2</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.12</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.mockito</groupId>
     <artifactId>mockito-core</artifactId>
     <version>2.20.1</version>
     <scope>test</scope>
   </dependency>
<!-- unit end -->

4. 基础知识

Java使用的Junit4常用的annotation

4.1 静态方法

@BeforeClass ----- 针对所有测试,只执行一次。方法签名必须是static void
@AfterClass ----- 针对所有测试,只执行一次。方法签名必须是static void

4.2 非静态方法

@Before ----- 初始化方法。每个@Test测试方法前都会执行一次
@Test ----- 测试方法。每个@Test测试方法都会创建一个实例对象
@After ----- 释放资源。每个@Test测试方法后都会执行一次

4.3 执行顺序

@BeforeClass -> {类的构造函数 -> @Before -> @Test -> @After} , 类的构造函数 -> {@Before -> @Test -> @After} … -> @AfterClass

其中每个@Test方法执行前会创建新的XxxTest实例, 单个@Test方法执行前后会执行@Before和@After方法

4.4 断言的常方法

assertEquals(100, x) ----- 相等
assertArrayEquals(100, x) ----- 数组相等
assertNull(x) ----- 断言为null
assertTrue(x) ----- 断言为true
assertNotEquals ----- 断言不相等
expected = Exception.class ----- 异常测试
timeout=1000 ----- 超时时间

5. 单元测试编写参考用例

详细代码可参考tech-summary-code

下面举例介绍四大类单元测试方法,这四类单元测试用例能基本满足大家日常编写单元测试的功能

序号 名称 说明
1 基础单元测试 基础用例
2 使用单例设计模式 单例是开发中最长使用的设计模式
3 依赖其他类 面向对象语言,封装是一大特性
4 类对象都是私有属性 类的属性都是私有,或者方法是私有的,可通过反射方法来编写单元测试

5.1 基础单元测试用例

基础单元测试是最被经常使用的

5.1.1 类CommonMethod.java

测试类CommonMethod.java有如下的对象公开方法,为每个方法编写单元测试

public class CommonMethod {
   

  public boolean success() {
   
    return true;
  }

  public int age() {
   
    return 100;
  }

  public int[] arrayOfInt() {
   
    return new int[]{
   1, 2, 3, 4};
  }

  public Object isNull() {
   
    return null;
  }

  public void throwException() {
   
    throw new NullPointerException();
  }

  public void timeout() throws InterruptedException {
   
    Thread.sleep(500L);
  }
}
5.1.2 测试类CommonMethodTest.java
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class CommonMethodTest {
   

  private CommonMethod method;

  /**
   * 仅执行一次
   */
  @BeforeClass
  public static void 
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值