定义:JMockit是一款Java类/接口/对象的Mock工具,目前广泛应用于Java应用程序的单元测试中。
使用:这里推荐大家访问JMockit中文网:http://jmockit.cn/index.htm;
里面的讲解很详细,也浅显易懂,注意多看看注释。
认识几个注解:
1. @Mocked:修饰的类/接口,是告诉JMockit,帮我生成一个Mocked对象,这个对象方法(包含静态方法)返回默认值。即如果返回类型为原始类型(short,int,float,double,long)就返回0,如果返回类型为String就返回null,如果返回类型是其它引用类型,则返回这个引用类型的Mocked对象;
2. @Injectable :也是告诉 JMockit生成一个Mocked对象,但@Injectable只是针对其修饰的实例,而@Mocked是针对其修饰类的所有实例。此外,@Injectable对类的静态方法,构造函数没有影响;
3. @Capturing:权限控制;
一个小例子:
新建一个Maven Project,在pom.xml文件中加上如下依赖:
<!-- 先声明jmockit的依赖(一定要先于junit) -->
<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>
再新建一个普通类,用来做mock的准备材料:
import java.util.Locale;
public class HelloJMockit {
// 向JMockit打招呼
public String sayHello() {
Locale locale = Locale.getDefault();
if (locale.equals(Locale.CHINA)) {
// 在中国,就说中文
return "你好,JMockit!";
} else {
// 在其它国家,就说英文
return "Hello,JMockit!";
}
}
}
再写一个测试类:
//JMockit的测试程序
public class ProgramConstructureTest {
// 这是一个测试属性
@Mocked
HelloJMockit helloJMockit;
@Mocked
HelloJMockit2 helloJMockit2;
/* 通过测试属性注入 */
@Test
public void test1() {
// 录制(Record)
new Expectations() { // 一个期望块
{
// HelloJMockit这个类被mock掉了,那么它调用sayHello()方法的返回值我们就可以自定义了
// 我们期待的结果原本是helloJMockit.sayHello()的返回值“你好,JMockit”,但是由于实际情况,我
// 们暂时不能得到这个值,那么我们就给它设置一个“假数据”,也就是“hello,david”,好让测试通过
helloJMockit.sayHello();
// 期待上述调用的返回是"hello,david",而不是返回"hello,JMockit"
result = "hello,david"; // 这个result是在Expectations抽象类中定义的,它是Object类型的,可以接收任何类型的数据。
// 这里面可以写任意个mock对象的调用,这些调用会被Expectations记录下来
helloJMockit2.sayHello();
result = "hello,MySql";
}
};
// 重放(Replay)
String msg = helloJMockit.sayHello();
String msg2 = helloJMockit2.sayHello();
Assert.assertTrue(msg.equals("hello,david")); // 使用junit的Assert.assertTrue()方法验证结果
Assert.assertTrue(msg2.equals("hello,MySql"));
// 验证(Verification)
new Verifications() {
{
helloJMockit.sayHello();
times = 1; // 录制代码块中的 helloJMockit.sayHello()方法指定执行一次
helloJMockit2.sayHello();
times = 1;
}
};
}
}