从 JMockit 系列的开篇 JMockit 之 Expectations 中了解到了一个最基本的 Mock 的写法,这里记录下在一个 Expectations 中如何同时 Mock 多个方法。基本框架是这样的:
new Expectations(MyService.class, ExternalService.class) {
{
MyService.prefix(“Unmi”);
result = “Welcome to website: “;
ExternalService.suffix(“Unmi”);
result = “http://unmi.cc”;
}
};
Java 语法告诉我们 new Expectations(){
{……}} 省略号处的代码会在 Expectations 匿名类实例初始化时被调用,那么其中对 result 的赋值便是新创建的 Expectations 匿名类实例的 result 的属性值,那两次的 result 赋值难道不是以最后一个为准吗,有点文章了。先来跑个例子,见识一下现象,由三个类组成,分别是:
1. MyService.java
package cc.unmi;
public class MyService {
public static String fetchData(String name){
return prefix(name) + ExternalService.suffix(name);
}
public static String prefix(String name){
throw new RuntimeException(“Not implemented yet!”);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
packagecc.unmi;
publicclassMyService{
publicstaticStringfetchData(Stringname){
returnprefix(name)+ExternalService.suffix(name);
}
publicstaticStringprefix(Stringname){
thrownewRuntimeException(“Not implemented yet!”);
}
}
2. ExternalService.java
package cc.unmi;
public class ExternalService {
public static String suffix(String name) {
throw new RuntimeException(“Not implemented yet!”);
}
}
1
2
3
4
5
6
7
8
packagecc.unmi;
publicclassExternalService{
publicstaticStringsuffix(Stringname){
thrownewRuntimeException(“Not implemented yet!”);
}
}
3. MyServiceTest.java
package cc.unmi;
import mockit.Expectations;
import org.junit.Assert;
import org.junit.Test;
public class MyServiceTest {
@Test
public void testFetchData() {
new Expectations(MyService.class, ExternalService.class) {
{
MyService.prefix(“Unmi”);
result = “Welcome to website: “;
ExternalService.suffix(“Unmi”);
result = “http://unmi.cc”;
}
};
String actual = MyService.fetchData(“Unmi”);
Assert.assertEquals(“Welcome to website: http://unmi.cc”, actual);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
packagecc.unmi;
importmockit.Expectations;
importorg.junit.Assert;
importorg.junit.Test;
publicclassMyServiceTest{
@Test
publicvoidtestFetchData(){
newExpectations(MyService.class,ExternalService.class){
{
MyService.prefix(“Unmi”);
result=”Welcome to website: “;
ExternalService.suffix(“Unmi”);
result=”http://unmi.cc”;
}
};
Stringactual=MyService.fetchData(“Unmi”);
Assert.assertEquals(“Welcome to website: http://unmi.cc”,actual);
}
}
MyService.fetchData(“Unmi”) 的返回有两部分组成,MyService.prefix() 和 ExternalService.suffix()。首先告知上面的测试是成功的,说明那两个方法都被有效 Mock 掉了,他们的结果分别是被两个 result 赋值代表了。new Expectations(){
{……}} 中的代码我们也无法从编译出的 MyServiceTest$ 找到痕迹,这就是 java.lang.instrument 的神通广大之处,一切尽在运行中,若要穷究底里,就得翻阅 JMockit 的源码了。