通過上面的例子,我們已經了解了Expectations的作用主要是用於錄制。即錄制類/對象的調用,返回值是什么。
錄制腳本規范
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
new
Expectations() {
// 這是一個Expectations匿名內部類
{
// 這是這個內部類的初始化代碼塊,我們在這里寫錄制腳本,腳本的格式要遵循下面的約定
//方法調用(可是類的靜態方法調用,也可以是對象的非靜態方法調用)
//result賦值要緊跟在方法調用后面
//...其它准備錄制腳本的代碼
//方法調用
//result賦值
}
};
還可以再寫
new
一個Expectations,只要出現在重放階段之前均有效。
new
Expectations() {
{
//...錄制腳本
}
};
|
Expectations主要有兩種使用方式。
-
通過引用外部類的Mock對象(@Injectabe,@Mocked,@Capturing)來錄制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//Expectations對外部類的mock對象進行錄制
public
class
ExpectationsTest {
@Mocked
Calendar cal;
@Test
public
void
testRecordOutside() {
new
Expectations() {
{
// 對cal.get方法進行錄制,並匹配參數 Calendar.YEAR
cal.get(Calendar.YEAR);
result =
2016
;
// 年份不再返回當前小時。而是返回2016年
// 對cal.get方法進行錄制,並匹配參數 Calendar.HOUR_OF_DAY
cal.get(Calendar.HOUR_OF_DAY);
result =
7
;
// 小時不再返回當前小時。而是返回早上7點鍾
}
};
Assert.assertTrue(cal.get(Calendar.YEAR) ==
2016
);
Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) ==
7
);
// 因為沒有錄制過,所以這里月份返回默認值 0
Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) ==
0
);
}
}
|
在這個例子中,在Expectations匿名內部類的初始代碼塊中,我們可以對外部類的任意成員變量,方法進行調用。大大便利我們書寫錄制腳本。
-
通過構建函數注入類/對象來錄制
在上面的例子中,我們通過引用外部類的Mock對象(@Injectabe,@Mocked,@Capturing)來錄制,可是無論是@Injectabe,@Mocked,@Capturing哪種Mock對象,都是對類的方法都mock了,可是有時候,我們只希望JMockit只mock類/對象的某一個方法。怎么辦? 看下面的例子就明白啦。
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
//通過Expectations對其構造函數mock對象進行錄制
public
class
ExpectationsConstructorTest2 {
// 把類傳入Expectations的構造函數
@Test
public
void
testRecordConstrutctor1() {
Calendar cal = Calendar.getInstance();
// 把待Mock的類傳入Expectations的構造函數,可以達到只mock類的部分行為的目的
new
Expectations(Calendar.
class
) {
{
// 只對get方法並且參數為Calendar.HOUR_OF_DAY進行錄制
cal.get(Calendar.HOUR_OF_DAY);
result =
7
;
// 小時永遠返回早上7點鍾
}
};
Calendar now = Calendar.getInstance();
// 因為下面的調用mock過了,小時永遠返回7點鍾了
Assert.assertTrue(now.get(Calendar.HOUR_OF_DAY) ==
7
);
// 因為下面的調用沒有mock過,所以方法的行為不受mock影響,
Assert.assertTrue(now.get(Calendar.DAY_OF_MONTH) == (
new
Date()).getDate());
}
// 把對象傳入Expectations的構造函數
@Test
public
void
testRecordConstrutctor2() {
Calendar cal = Calendar.getInstance();
// 把待Mock的對象傳入Expectations的構造函數,可以達到只mock類的部分行為的目的,但只對這個對象影響
new
Expectations(cal) {
{
// 只對get方法並且參數為Calendar.HOUR_OF_DAY進行錄制
cal.get(Calendar.HOUR_OF_DAY);
result =
7
;
// 小時永遠返回早上7點鍾
}
};
// 因為下面的調用mock過了,小時永遠返回7點鍾了
Assert.assertTrue(cal.get(Calendar.HOUR_OF_DAY) ==
7
);
// 因為下面的調用沒有mock過,所以方法的行為不受mock影響,
Assert.assertTrue(cal.get(Calendar.DAY_OF_MONTH) == (
new
Date()).getDate());
// now是另一個對象,上面錄制只對cal對象的影響,所以now的方法行為沒有任何變化
Calendar now = Calendar.getInstance();
// 不受mock影響
Assert.assertTrue(now.get(Calendar.HOUR_OF_DAY) == (
new
Date()).getHours());
// 不受mock影響
Assert.assertTrue(now.get(Calendar.DAY_OF_MONTH) == (
new
Date()).getDate());
}
}
|