1.JMockit的两套API实现方式
JMockit提供了两套API,一套叫做Expectations,用于基于行为的单元测试;一套叫做MockUp,用于基于状态的单元测试。 ①.Expectations
record : 录制将要被调用的方法和返回值
参数类型可以是anyXyz,anyString/也可以是with,with的范围更精准
replay:调用录制的方法
verify:基于行为的验证(验证调用次数,验证调用顺序)也可以用assert断言验证
②. MockUp(匿名内部类)
mock-up类是继承 | |
1.继承 | 2.实例 |
public class testName extends MockUp<Dependency> { @Mock public void mockMethod() {} } | public class testName { new MockUp<T>(T.class) { @Mock public void mockMethod() {} }; } |
2.Jmockit常用注解
①@Tested和@Mocked
用@Tested和@Mocked标注被测试类,在运行测试方法时,如果该实例仍然为null,JMockit会自动组装相关mock对象,进行初始化。在组装被测试类过程中,相关mock对象必须使用@Injectable标记,非mock对象除了使用@Injectable标记,还需要有明确初始值。
②@Capturing
使用@Capturing标注基类/接口,所有实现类会被mock:
abstract方法或者接口方法不能被直接mock。
3.参考学习网址
①.JMockit中文网
http://jmockit.cn/index.htm
②.JMockit中文教程
https://www.jianshu.com/c/cfe7310a18ff
4.示例代码
//要测试的类,不同的方法(无返回值,有参数,有返回值,方法直接内部调用,实体类,私有方法)
public class SayHelloUndertest {
public void initHello(){
System.out.println("我是没有参数,没有返回值的方法,只看调用次数就ok");
}
public String sayHello() {
System.out.println("我是有返回值");
return "hello,JMockit";
}
public Student initStudent(String sName,Integer age){
Student student=new Student();
student.setAge(age);
String name =initStudentName(sName);
student.setName(name);
return student;
}
public String initStudentName(String name ){
return name ;
}
private String privateMethod(){
return "privateMethod";
}
}
/**
* Expectations的API验证方式
* 录制-回放-验证
* @throws Exception
*/
@RunWith(JMockit.class)
public class ExpectationsTest {
@Mocked
SayHelloUndertest sayHelloUndertest;
@Test
public void testName() throws Exception {
//录制
new Expectations(){
{
sayHelloUndertest.sayHello();
result="exp:sayHello";
//参数类型可以是anyXyz,anyString/也可以是with,with的范围更精准
sayHelloUndertest.initStudentName(anyString);
result="花花";
}
};
//回放
sayHelloUndertest.sayHello();
sayHelloUndertest.initStudentName("lala");
//验证(两种方式1.断言;2.Verifications)
new Verifications() {
{
sayHelloUndertest.sayHello();
times=1;
}
};
//String mString=sayHelloUndertest.sayHello();
//assertTrue(mString.equals("exp:sayHello"));
String mString=sayHelloUndertest.initStudentName("");
assertTrue(mString.equals("花花"));
}
}
/**
* 使用mockUp的API验证方式
*
* @author junjiexu3
*
*/
@RunWith(JMockit.class)
public class MockUpTest {
@Test
public void testName() throws Exception {
new MockUp<SayHelloUndertest>(SayHelloUndertest.class) {
// 公共方法无返回值
@Mock
public void initHello() {
System.out.println("ok");
}
// 公共方法有返回值
@Mock
public String sayHello() {
return "MockUp:hello,JMockit";
}
// 公共方法返回实体且里面方法中包含mock方法
@Mock
public Student initStudent(String sName, Integer age) {
Student student = new Student();
student.setAge(age);
student.setName(initStudentName(sName));
return student;
}
@Mock
public String initStudentName(String name) {
return "YOYO";
}
};
SayHelloUndertest undertest = new SayHelloUndertest();
// 验证无返回值的
undertest.initHello();
// 验证有返回值的(public)
String msg = undertest.sayHello();
assertTrue(msg.equals("MockUp:hello,JMockit"));
// 验证有返回值的(实体)
Student student = new Student();
// student=undertest.initStudent("Jessise", 12);
student = undertest.initStudent("123", 12);
assertTrue(student.getName().equals("YOYO"));
}
//使用静态方法,通过继承mockUp实现私有方法的调用
public static class privateMethodMock extends MockUp<SayHelloUndertest> {
// mock私有方法
@Mock
private String privateMethod() {
return "mock1:privateMethod";
}
}
@Test
public void testPrivateMethod() throws Exception {
assertTrue(new privateMethodMock().privateMethod().equals("mock1:privateMethod"));
}