关于单元测试,我们先上一段代码,如下示例:
public String sayHello() {
Locale locale = Locale.getDefault();
if (locale.equals(Locale.CHINA)) {
// 在中国,就说中文
return "你好,世界!";
} else {
// 在其它国家,就说英文
return "Hello,world!";
}
}
如果我们需要对这段代码做单元测试,而且要求代码覆盖率能够达到100%,你会怎么做呢?由于Locale是根据操作系统使用的语言不同而不同,你可能会说需要在不同的操作系统语言环境下进行单元测试,如果这样你就out了。如果你知道Mock方法,你肯定会说我们只需要通过Mock方法,模拟不同的语言对象Locale就可以进行测试且覆盖率100%。下面小编来简单介绍下讲讲如何Mock测试。
什么是Mock?
Mock英文翻译过来就是:“模仿”,“假的”;所以顾名思义,Mock测试就是在单元测试过程中,对于某些不容易构造或者不容易获取的对象,用一个模拟的对象来创建以便测试的测试方法。这个模拟对象就是Mock对象。通俗的讲就是Mock对象就是在测试一个对象A时,我们构造一些假的对象来参与A之间的交互,这些构造的假的对象就是Mock对象,而这些Mock对象的行为是我们事先设定且符合预期,通过这些Mock对象我们就能比较容易来测试A在正常逻辑,异常逻辑或压力情况下是否正常工作。
为什么要使用Mock?
在单元测试中,模拟对象可以模拟复杂的、真实的对象的行为, 如果真实的对象无法放入单元测试中,使用模拟对象就对我们进行单元测试有很大的帮助。
引入Mock最大的优势在于:Mock的行为固定,它确保当你访问某个Mock的方法时总是直接就返回的预期结果。使用Mock的优势如下:
Mock的使用场景
JMockit的简单使用
在Java语言方面主要的Mock测试框架有JMockit,Mockito,JMock,MockCreator,Mockrunner,EasyMock,MockMaker等;由于JMockit的API易用,丰富,所以小编推荐大家学习使用JMockit。下面为大家介绍如何使用JMockit。
一般使用JMockit的步骤:
1、模拟任何外部依赖并将模拟对象插入测试代码中;
2、执行测试代码;
3、验证代码是否按照预期执行;
配置依赖
一般目前的功能大都是Maven工程,所以小编就以Maven工程为例来说明如何使用JMockit。首先在pom文件中引入JMockit依赖,如下图所示:
<!-- 先声明jmockit的依赖 -->
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.36</version>
<scope>test</scope>
</dependency>
<!-- 再声明junit的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
接下来我们就来模拟外部对象来对文章开始部分的代码进行单元测试,JMockit的Mock有两种方式:
1、 用Expectations来Mock,完整代码如下:
@Test
public void testSayHelloAtChina() {
//用Expectations来Mock
//假设当前位置是在中国
new Expectations(Locale.class) {
{
Locale.getDefault();
result = Locale.CHINA;
}
};
Assert.assertTrue("你好,世界!".equals((new HelloJMockit()).sayHello()));
}
@Test
public void testSayHelloAtUS() {
//用Expectations来Mock
//假设当前位置是在美国
new Expectations(Locale.class) {
{
Locale.getDefault();
result = Locale.US;
}
};
Assert.assertTrue("Hello,world!".equals((new HelloJMockit()).sayHello()));
}
2、用MockUp来Mock类,完整代码如下:
@Test
public void testSayHelloAtChina1() {
//用MockUp来Mock类
//假设当前位置是在中国
new MockUp<Locale>(Locale.class) {
//想Mock哪个方法,就给哪个方法加上@Mock, 没有@Mock的方法,不受影响
@Mock
public Locale getDefault() {
return Locale.CHINA;
}
};
Assert.assertTrue("你好,世界!".equals((new HelloJMockit()).sayHello()));
}
@Test
public void testSayHelloAtUS1() {
//用MockUp来Mock类
//假设当前位置是在美国
new MockUp<Locale>(Locale.class) {
//想Mock哪个方法,就给哪个方法加上@Mock, 没有@Mock的方法,不受影响
@Mock
public Locale getDefault() {
return Locale.US;
}
};
Assert.assertTrue("Hello,world!".equals((new HelloJMockit()).sayHello()));
}
代码完成后执行测试结果如下:
小结
以上为大家介绍了什么叫Mock测试以及如何使用JMockit进行Mock测试,大家是不是觉得更加容易进行单元测试了!需要更加深入的学习JMockit的同学可以进入JMockit中文网(http://jmockit.cn)学习。当然除了JMockit外,Mockito,EasyMock也是目前比较常用的Mock框架,它们的原理差不太多,大家可以选择学习。对这篇文章感兴趣的同学可以关注我们的微信公众号与小编一起交流探讨,后续我们还提供更多精彩内容。