单元测试的写法

近日,项目上要求提升单元测试覆盖率,在补覆盖率过程中,把自己的一些写法分享出来,如果能帮助同样需要补覆盖率的你少走点弯路,那就再好不过了>_<

1.引入依赖

引入Mock依赖
<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-core</artifactId>
   <version>1.10.19</version>
   <scope>test</scope>
</dependency>
<!-- 视情况引入powermock依赖 -->
<dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-core</artifactId>
   <version>1.6.4</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-module-junit4</artifactId>
   <version>1.6.4</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-api-mockito</artifactId>
   <version>1.6.4</version>
   <scope>test</scope>
</dependency>
引入junit依赖
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <scope>test</scope>
   <optional>true</optional>
</dependency>

Mockito和PowerMockito版本对应关系
Mockito | PowerMock
2.0.0-beta - 2.0.42-beta | 1.6.5+
1.10.19 | 1.6.4
1.10.8 - 1.10.x | 1.6.2+
1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6
1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12
1.8.5 | 1.3.9 - 1.4.9
1.8.4 | 1.3.7 & 1.3.8
1.8.3 | 1.3.6
1.8.1 & 1.8.2 | 1.3.5
1.8 | 1.3
1.7 | 1.2.5

2.Mock对象

这里主要使用注解的方式:
@InjectMocks:用于Mock你要测试的类
@Mock:用于注入你要测试的类的变量(可以稍微理解成相当于原来类里的@Resource或者@Autowired)

单元测试的写法:
0.首先写一个MockitoBasedTest类
1.首先在测试方法中首先模拟出该方法的参数;
2.如果有调用其他service的方法,且返回值后续需要判断,则需要模拟该service的方法,用Mockito.when().thenReturn()来进行模拟,模拟时需要自己给返回参数赋值以便通过判断;
如果无返回值,可以用Mockito.doNothing().when()来进行模拟;
3.最后,用你在@InjectMocks下引入的类调用方法完成单元测试;

PS:如果遇到私有变量的情况,可以通过反射的方法来赋值;
如果在测试方法中某一个方法被多次调用,可以在thenReturn()里添加多个返回值来实现依次返回不同的值;

示例代码如下:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public abstract class MockitoBasedTest {
    @Before
    public void setUp() throws Exception {
        // 初始化测试用例类中由Mockito的注解标注的所有模拟对象
        MockitoAnnotations.initMocks(this);
    }
}

public class FreezeMoneyTaskTest extends MockitoBasedTest {
    @InjectMocks
    private FreezeMoneyTask freezeMoneyTask;
    @Mock
    private MoneyRefundDas moneyRefundDas;
    @Mock
    private IMoneyRefundService iMoneyRefundService;

    @Test
    public void before() {
        TaskMessage taskMessage = new TaskMessage();
        freezeMoneyTask.before(taskMessage);
    }

    @Test
    public void execute() throws Exception {
        // 初始化方法参数
        TaskMessage taskMessage = new TaskMessage();
        // 通过反射的方法来为私有变量赋值
        int recordNum = 2;
        Field recordNum1 = freezeMoneyTask.getClass().getDeclaredField("recordNum");
        recordNum1.setAccessible(true);
        recordNum1.set(freezeMoneyTask,recordNum);
        // 有返回值的写法
        List<MoneyRefundEo> select = new ArrayList<>();
        MoneyRefundEo moneyRefundEo = new MoneyRefundEo();
        moneyRefundEo.setCompensateNum(1);
        select.add(moneyRefundEo);
        Mockito.when(moneyRefundDas.selectRetryRefundList(anyInt(), anyString())).thenReturn(select);
        // 无返回值的写法
        Mockito.doNothing().when(moneyRefundDas).updateSelective(anyObject());
        // 执行测试
        freezeMoneyTask.execute(taskMessage);
    }
}

其他细节可以参考这位大佬的文章:https://zhuanlan.zhihu.com/p/101026707

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值