JMockit常用操作
2017-11-30 转自:
目录
1
1.1 1.2 2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 2.2.3源代码:
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 class SimpleTool { public String fun1(String str) { return "real: public String fun1(" + str + ")"; } private String fun2(String str) { return "real: private String fun2(" + str + ")"; } public String fun3(String str) { return "real: public String fun3(" + str + ")"; } public String fun4(String str) { return fun2(str); }}
UseSimpleTool.java代码如下:
public class UseSimpleTool { public String fun1(String name) { SimpleTool simpleTool = new SimpleTool(); return simpleTool.fun1(name); }}
2.1 Status-based
2.1.1 实例1:Mocked - 被Mock修饰的对象,对应的类和实例都会受影响
import com.demo.SimpleTool;import com.demo.UseSimpleTool;import mockit.Expectations;import mockit.Mocked;import mockit.Verifications;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(JMockit.class)public class MockedAnnotationTest { @Mocked SimpleTool simpleTool; @Test public void testExpectation() { //未mock函数返回null new Expectations() { { simpleTool.fun1(anyString); result = "MOCK"; } }; System.out.println(simpleTool.fun1("param")); System.out.println(simpleTool.fun3("param")); System.out.println(new UseSimpleTool().fun1("param")); new Verifications() { { simpleTool.fun1(anyString); times = 2; } }; }}
输出:
MOCKnullMOCK
2.1.2 实例2:injectable - 仅Mock被修饰的对象
import com.demo.SimpleTool;import com.demo.UseSimpleTool;import mockit.Expectations;import mockit.Injectable;import mockit.Verifications;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(JMockit.class)public class InjectableAnnotationTest { @Injectable SimpleTool simpleTool; @Test public void testExpectation() { //未mock函数返回null new Expectations() { { simpleTool.fun1(anyString); result = "MOCK"; } }; System.out.println(simpleTool.fun1("param")); System.out.println(simpleTool.fun3("param")); System.out.println(new UseSimpleTool().fun1("param")); new Verifications() { { simpleTool.fun1(anyString); times = 1; } }; }}
输出:
MOCKnullreal: public String fun1(param)
2.1.3 实例3:Delegate - 自己指定返回值,适合那种需要参数决定返回值的场景
import com.demo.SimpleTool;import com.demo.UseSimpleTool;import mockit.Delegate;import mockit.Expectations;import mockit.Mocked;import mockit.Verifications;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(JMockit.class)public class DelegateResultTest { @Mocked SimpleTool simpleTool; @Test public void testExpectation() { new Expectations() { { simpleTool.fun1(anyString); result = new Delegate() { public String 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")); new Verifications() { { simpleTool.fun1(anyString); times = 2; } }; }}
输出:
MOCK0nullMOCK1
2.2 Behavior-based
2.2.1 实例1:Mock对象公有方法
import com.demo.SimpleTool;import com.demo.UseSimpleTool;import mockit.Mock;import mockit.MockUp;import org.junit.Test;public class MockPublicMethodTest { @Test public void testMockUp() { //影响该类所有实例 new MockUp(){ //未mock函数不受影响 @Mock public String fun1(String str) { return "(MOCK)"; } }; SimpleTool simpleTool = new SimpleTool(); System.out.println(simpleTool.fun1("param")); System.out.println(simpleTool.fun3("param")); System.out.println(new UseSimpleTool().fun1("param")); }}
输出:
(MOCK)real: public String fun3(param)(MOCK)
2.2.2 实例2:Mock对象私有方法
import com.demo.SimpleTool;import com.demo.UseSimpleTool;import mockit.Mock;import mockit.MockUp;import org.junit.Test;public class MockPublicMethodTest { @Test public void testMockUp() { //影响该类所有实例 new MockUp(){ //未mock函数不受影响 @Mock public String fun1(String str) { return "(MOCK)"; } }; SimpleTool simpleTool = new SimpleTool(); System.out.println(simpleTool.fun1("param")); System.out.println(simpleTool.fun3("param")); System.out.println(new UseSimpleTool().fun1("param")); }}
输出:
real: public String fun1(param)real: public String fun3(param)(MOCK)
2.2.3 实例3:Mock接口
两个类作为测试对象:SimpleInterface、SimpleInterfaceImpl
SimpleInterface代码如下:
public interface SimpleInterface { String getCityName(); String getAreaName();}
SimpleInterfaceImpl代码如下:
public class SimpleInterfaceImpl implements SimpleInterface { public String getCityName() { return "default city"; } public String getAreaName() { return "default area"; }}
实例
import com.demo.SimpleInterface;import com.demo.SimpleInterfaceImpl;import mockit.Injectable;import mockit.Mock;import mockit.MockUp;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;@RunWith(JMockit.class)public class MockInterfaceTest { //此处使用Injectable和Mocked为一样的效果 @Injectable SimpleInterface simpleInterface; @Test public void testUpper() throws Exception { SimpleInterface mockInstance = new MockUp() { @Mock public String getCityName() { return "BEIJING(MOCK)"; } @Mock public String 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 = new SimpleInterfaceImpl(); System.out.println(simpleInterfaceImpl.getCityName()); System.out.println(simpleInterfaceImpl.getAreaName()); }}
输出:
BEIJING(MOCK)HUABEI(MOCK)nullnulldefault citydefault area