JMockit是一款Java类/接口/对象的Mock工具,目前广泛应用于Java应用程序的单元测试中
一句话说明功能:你需要什么就可以mock什么。(比如本地没有Redis但是开发时又需要用到,那么就可以mock一个Redis的功能来隔离对Redis的依赖)
record(录制)---- replay(回放) ---- verify(验证)
1、record : 设置将要被调用的方法和返回值。
2、replay:调用录制的方法,被录制的方法调用会被JMockit拦截并重定向到record阶段设定的行为。
3、verify:基于行为的验证,测试是否正确调用了依赖类,包括:调用了哪些方法;通过怎样的参数;调用了多少次;调用的相对顺序等。可以使用times,minTimes,maxTimes来验证。
<!-- 先声明jmockit的依赖 -->
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.36</version>
<scope>test</scope>
</dependency>
<!-- 如果没有引入junit依赖就加上下面依赖 -->
<!-- 再声明junit的依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
将 jmockitInt() 方法的返回值 mock 成 100
public class JMockitDemo1001 {
// 获取int值
public int jmockitInt(){
return 10;
}
}
// JMockit测试
@Test
public void jmockitIntTest(){
JMockitDemo1001 jMockitDemo1001 = new JMockitDemo1001();
// mock前返回值为 10
Assert.assertEquals(jMockitDemo1001.jmockitInt(), 10);
// 1、录制
new Expectations(JMockitDemo1001.class) {
{
// 将该方法返回值 mock 为 100
jMockitDemo1001.jmockitInt();
result = 100;
}
};
// 2、回放
Assert.assertEquals(jMockitDemo1001.jmockitInt(), 100);
// 3、验证
new Verifications(){
{
jMockitDemo1001.jmockitInt();
times = 1;
}
};
}
public class JMockitMocked {
public static String strDataStatic = "strDataStatic";
public static int intDataStatic = 10;
public String strData = "strData";
public int intData = 1;
public static String getStrDataStatic(){
return strDataStatic;
}
public static int getIntDataStatic(){
return intDataStatic;
}
public String getStrData(){
return strData;
}
public int getIntData(){
return intData;
}
}
// mocked测试
public class JMockitMockedTest {
@Mocked
JMockitMocked jMockitMocked;
@Test
public void test1001(){
System.out.println(JMockitMocked.strDataStatic); // strDataStatic
System.out.println(JMockitMocked.intDataStatic); // 10
System.out.println(jMockitMocked.strData); // null
System.out.println(jMockitMocked.intData); // 0
System.out.println(JMockitMocked.getStrDataStatic()); // null
System.out.println(JMockitMocked.getIntDataStatic()); // 0
System.out.println(jMockitMocked.getStrData()); // null
System.out.println(jMockitMocked.getIntData()); // 0
}
}
@Injectable 也是告诉 JMockit生成一个Mocked对象,但@Injectable只是针对其修饰的实例,而@Mocked是针对其修饰类的所有实例
public class JMockitMocked {
public static String strDataStatic = "strDataStatic";
public static int intDataStatic = 10;
public String strData = "strData";
public int intData = 1;
public static String getStrDataStatic(){
return strDataStatic;
}
public static int getIntDataStatic(){
return intDataStatic;
}
public String getStrData(){
return strData;
}
public int getIntData(){
return intData;
}
}
// mock测试
public class JMockitInjectableAndTestedTest {
// @Mocked
@Test
public void test1001(@Mocked JMockitInjectableAndTested jMockitInjectableAndTested){
System.out.println(JMockitInjectableAndTested.getStrDataStatic()); // null
System.out.println(JMockitInjectableAndTested.getIntDataStatic()); // 0
System.out.println(jMockitInjectableAndTested.getStrData()); // null
System.out.println(jMockitInjectableAndTested.getIntData()); // 0
}
// @Injectable
@Test
public void test1002(@Injectable JMockitInjectableAndTested jMockitInjectableAndTested){
System.out.println(JMockitInjectableAndTested.getStrDataStatic()); // strDataStatic
System.out.println(JMockitInjectableAndTested.getIntDataStatic()); // 10
System.out.println(jMockitInjectableAndTested.getStrData()); // null
System.out.println(jMockitInjectableAndTested.getIntData()); // 0
}
}
MockUp & @Mock 的联合使用可以只 mock 对象的部分方法(当需要 mock 整个对象就可以考虑使用 @Mocked 或 @Injectable)
public class JMockitMockUpAndMock {
public int getIntData1001(int num){
return num;
}
public int getIntData1002(int num){
return num;
}
}
// mock测试
public class JMockitMockUpAndMockTest {
@Test
public void test1001(){
// 只需要把JMockitMockUpAndMock类传入MockUp类的构造函数
new MockUp<JMockitMockUpAndMock>(JMockitMockUpAndMock.class) {
// 想Mock哪个方法,就给哪个方法加上@Mock, 没有@Mock的方法,不受影响
@Mock
public int getIntData1001(int num) {
return 10 * num;
}
};
JMockitMockUpAndMock jMockitMockUpAndMock = new JMockitMockUpAndMock();
System.out.println(jMockitMockUpAndMock.getIntData1001(2)); // 20
System.out.println(jMockitMockUpAndMock.getIntData1002(2)); // 2
}
}