JMockit常用操作
目录
1 基本概念
1.1 常用注解
@Mocked:被修饰的对象将会被Mock,对应的类和实例都会受影响(同一个测试用例中)
@Injectable:仅Mock被修饰的对象
@Capturing:可以mock接口以及其所有的实现类
@Mock:MockUp模式中,指定被Fake的方法
1.2 常用的类
Expectations:期望,指定的方法必须被调用
StrictExpectations:严格的期望,指定方法必须按照顺序调用
NonStrictExpectations:非严格的期望,是否调用和顺序不作要求
Verifications:验证,一般配合NonStrictExpectations来使用
Invocation:工具类,可以获取调用信息
Delegate:自己指定返回值,适合那种需要参数决定返回值的场景,只需指定匿名子类就可以。
MockUp:模拟函数实现
Deencapsulation:反射工具类
2 实例演示
现有两个类作为测试对象: SimpleTool.java、UseSimpleTool.java
SimpleTool.java代码如下:
public classSimpleTool {publicString fun1(String str) {return "real: public String fun1(" + str + ")";
}privateString fun2(String str) {return "real: private String fun2(" + str + ")";
}publicString fun3(String str) {return "real: public String fun3(" + str + ")";
}publicString fun4(String str) {returnfun2(str);
}
}
View Code
UseSimpleTool.java代码如下:
public classUseSimpleTool {publicString fun1(String name) {
SimpleTool simpleTool= newSimpleTool();returnsimpleTool.fun1(name);
}
}
View Code
2.1 Status-based
2.1.1 实例1:Mocked - 被Mock修饰的对象,对应的类和实例都会受影响
importcom.demo.SimpleTool;importcom.demo.UseSimpleTool;importmockit.Expectations;importmockit.Mocked;importmockit.Verifications;importmockit.integration.junit4.JMockit;importorg.junit.Test;importorg.junit.runner.RunWith;
@RunWith(JMockit.class)public classMockedAnnotationTest {
@Mocked
SimpleTool simpleTool;
@Testpublic voidtestExpectation() {//未mock函数返回null
newExpectations() {
{
simpleTool.fun1(anyString);
result= "MOCK";
}
};
System.out.println(simpleTool.fun1("param"));
System.out.println(simpleTool.fun3("param"));
System.out.println(new UseSimpleTool().fun1("param"));newVerifications() {
{
simpleTool.fun1(anyString);
times= 2;
}
};
}
}
View Code
输出:
MOCK
null
MOCK
2.1.2 实例2:injectable - 仅Mock被修饰的对象
importcom.demo.SimpleTool;importcom.demo.UseSimpleTool;importmockit.Expectations;importmockit.Injectable;importmockit.Verifications;importmockit.integration.junit4.JMockit;importorg.junit.Test;importorg.junit.runner.RunWith;
@RunWith(JMockit.class)public classInjectableAnnotationTest {
@Injectable
SimpleTool simpleTool;
@Testpublic voidtestExpectation() {//未mock函数返回null
newExpectations() {
{
simpleTool.fun1(anyString);
result= "MOCK";
}
};
System.out.println(simpleTool.fun1("param"));
System.out.println(simpleTool.fun3("param"));
System.out.println(new UseSimpleTool().fun1("param"));newVerifications() {
{
simpleTool.fun1(anyString);
times= 1;
}
};
}
}
View Code
输出:
MOCKnullreal:public String fun1(param)
2.1.3 实例3:Delegate - 自己指定返回值,适合那种需要参数决定返回值的场景
importcom.demo.SimpleTool;importcom.demo.UseSimpleTool;importmockit.Delegate;importmockit.Expectations;importmockit.Mocked;importmockit.Verifications;importmockit.integration.junit4.JMockit;importorg.junit.Test;importorg.junit.runner.RunWith;
@RunWith(JMockit.class)public classDelegateResultTest {
@Mocked
SimpleTool simpleTool;
@Testpublic voidtestExpectation() {newExpectations() {
{
simpleTool.fun1(anyString);
result= new Delegate() {publicString aDelegateMethod(String str) {return str.equals("param0") ? "MOCK0" : "MOCK1";
}
};
}
};
System.out.println(simpleTool.fun1("param0"));
System.out.println(simpleTool.fun3("param"));
System.out.println(new UseSimpleTool().fun1("param1"));newVerifications() {
{
simpleTool.fun1(anyString);
times= 2;
}
};
}
}
View Code
输出:
MOCK0nullMOCK1
2.2 Behavior-based
2.2.1 实例1:Mock对象公有方法
importcom.demo.SimpleTool;importcom.demo.UseSimpleTool;importmockit.Mock;importmockit.MockUp;importorg.junit.Test;public classMockPublicMethodTest {
@Testpublic voidtestMockUp() {//影响该类所有实例
new MockUp(){//未mock函数不受影响
@MockpublicString fun1(String str) {return "(MOCK)";
}
};
SimpleTool simpleTool= newSimpleTool();
System.out.println(simpleTool.fun1("param"));
System.out.println(simpleTool.fun3("param"));
System.out.println(new UseSimpleTool().fun1("param"));
}
}
View Code
输出:
(MOCK)
real:publicString fun3(param)
(MOCK)
2.2.2 实例2:Mock对象私有方法
importcom.demo.SimpleTool;importcom.demo.UseSimpleTool;importmockit.Mock;importmockit.MockUp;importorg.junit.Test;public classMockPublicMethodTest {
@Testpublic voidtestMockUp() {//影响该类所有实例
new MockUp(){//未mock函数不受影响
@MockpublicString fun1(String str) {return "(MOCK)";
}
};
SimpleTool simpleTool= newSimpleTool();
System.out.println(simpleTool.fun1("param"));
System.out.println(simpleTool.fun3("param"));
System.out.println(new UseSimpleTool().fun1("param"));
}
}
View Code
输出:
real: publicString fun1(param)
real:publicString fun3(param)
(MOCK)
2.2.3 实例3:Mock接口
两个类作为测试对象:SimpleInterface、SimpleInterfaceImpl
SimpleInterface代码如下:
public interfaceSimpleInterface {
String getCityName();
String getAreaName();
}
SimpleInterfaceImpl代码如下:
public class SimpleInterfaceImpl implementsSimpleInterface {publicString getCityName() {return "default city";
}publicString getAreaName() {return "default area";
}
}
实例
importcom.demo.SimpleInterface;importcom.demo.SimpleInterfaceImpl;importmockit.Injectable;importmockit.Mock;importmockit.MockUp;importmockit.integration.junit4.JMockit;importorg.junit.Test;importorg.junit.runner.RunWith;
@RunWith(JMockit.class)public classMockInterfaceTest {//此处使用Injectable和Mocked为一样的效果
@Injectable
SimpleInterface simpleInterface;
@Testpublic void testUpper() throwsException {
SimpleInterface mockInstance= new MockUp() {
@MockpublicString getCityName() {return "BEIJING(MOCK)";
}
@MockpublicString getAreaName() {return "HUABEI(MOCK)";
}
}.getMockInstance();
System.out.println(mockInstance.getCityName());
System.out.println(mockInstance.getAreaName());
System.out.println(simpleInterface.getCityName());
System.out.println(simpleInterface.getAreaName());
SimpleInterfaceImpl simpleInterfaceImpl= newSimpleInterfaceImpl();
System.out.println(simpleInterfaceImpl.getCityName());
System.out.println(simpleInterfaceImpl.getAreaName());
}
}
View Code
输出:
BEIJING(MOCK)
HUABEI(MOCK)null
null
defaultcitydefault area