Jmockit使用笔记
测试框架Jmockit集合junit使用
@RunWith(JMockit.class)
写在测试案例类上的注解
@Tested
在测试案例中,写在我们要测试的类上面, 一般用实现类
@Injectable
在测试案例中声明那些我们要测试的类中通过@Autowired注入的类
代码展示如下:
/**
* @author: xinruoxiangyang9010
* 我们要测试的业务代码
*/
@Service
public class MyServicempl implements MyService {
@Autowired
private MyMapper myMapper;
@Override
public String testMethod() {
return "myService";
}
}
/**
* @author: xinruoxiangyang9010
* 测试案例
*/
@RunWith(JMockit.class)
public class MyServicemplTest {
@Injectable
private MyMapper myMapper;
@Tested
private MyServicempl myServicempl;
@Test
public void testMethod() {
String result = myServicempl.testMethod();
assertEquals("myService", result);
}
}
如果测试类中忘了用@Injectable修饰被测试代码中所有的注入对象时, 哪怕遗漏了一个, 就会有如下报错信息:
java.lang.IllegalStateException: Missing @Injectable for field "xxx.xxx.xxx.MyMapper myMapper" in MyServicempl
@Mocked
与@Injectable类似都是在mock对象(这里的mock是指模拟的意思), 但又有区别, @Injectable只会影响被修改的那一个对象, 但是@Mocked 会影响所他所修饰的对象及其子类, 哪怕这个对象时你new出来的; 调用mock对象的方法时不会调用原代码, 会交给JMockit处理, 均返回默认值(int,short,double等返回0,String返回null)
@Mocked
private User user;
Expectations
字面解释预期,就是指定方法在调用时,返回我们想要的结果(当然有时候结果要我们自己提前准备好)
指定代码中使用的工具类返回我们想要的值
/**
* @author: xinruoxiangyang9010
* 业务代码
*/
public class MyStringUtil {
public static String getUUID() {
return "id_1";
}
public static String getUUID2() {
return "id_2";
}
}
/**
* @author: xinruoxiangyang9010
* 测试案例
*/
@RunWith(JMockit.class)
public class MyStringUtilTest {
@Test
public void getUUID() {
new Expectations(MyStringUtil.class) {
{
MyStringUtil.getUUID();
result = "123";
}
};
String resultString = MyStringUtil.getUUID();
assertEquals("123", resultString);
}
}
注意:
第一点 new Expectations(MyStringUtil.class) 这里要把MyStringUtil.class作为参数传进去
第二点 如果Expectations中写的方法, 实际却没有被调用,则测试案例会出现如下错误
@Test
public void getUUID_test2() {
new Expectations(MyStringUtil.class) {
{
MyStringUtil.getUUID();
result = "123";
MyStringUtil.getUUID2();
result = "222";
}
};
String resultString = MyStringUtil.getUUID();
assertEquals("123", resultString);
}
Missing 1 invocation to:
xin.ruo.xiang.yang.jmockit.MyStringUtil#getUUID2()
Caused by: Missing invocations
at xin.ruo.xiang.yang.jmockit.MyStringUtil.getUUID2(MyStringUtil.java)
at xin.ruo.xiang.yang.jmockit.MyStringUtilTest$2.<init>(MyStringUtilTest.java:35)
at xin.ruo.xiang.yang.jmockit.MyStringUtilTest.getUUID_test2(MyStringUtilTest.java:31)
在Expectations中指定某个方法被调用多次,返回不同结果
@Test
public void getUUID_test3() {
new Expectations(MyStringUtil.class) {
{
MyStringUtil.getUUID();
result = "111";
result = "222";
result = "333";
}
};
String resultString = MyStringUtil.getUUID();
assertEquals("111", resultString);
String resultString2 = MyStringUtil.getUUID();
assertEquals("222", resultString2);
String resultString3 = MyStringUtil.getUUID();
assertEquals("333", resultString3);
}
这里结合Expectations的使用对@Mocked与@Injectable的不同再进行一下解释
/**
* @author: xinruoxiangyang9010
* 业务代码
*/
public class DiffServiceImpl implements DiffService {
public String method() {
return "real";
}
}
/**
* @author: xinruoxiangyang9010
* 测试案例
*/
@RunWith(JMockit.class)
public class MockAndInjectTest {
@Test
public void testMock(@Mocked DiffServiceImpl diffService) {
new Expectations() {
{
diffService.method();
result = "mockMethod";
}
};
assertEquals("mockMethod", diffService.method());
// @Mocked修饰的变量,即便是再new出来的,也会按照上面我们mock的结果返回
assertEquals("mockMethod", new DiffServiceImpl().method());
}
@Test
public void testInjectable (@Injectable DiffServiceImpl diffService) {
new Expectations() {
{
diffService.method();
result = "mockMethod";
}
};
assertEquals("mockMethod", diffService.method());
// 注意这里结果的不同, 在对@Injectable修饰的对象进行Expectations指定结果时
// 受影响的只是被修饰的对象,如果我们new一个示例出来,是不会受Expectations影响的
assertEquals("real", new DiffServiceImpl().method());
}
}