jmockit中文網 expectations 入門


通過上面的例子,我們已經了解了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主要有兩種使用方式。

    1. 通過引用外部類的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匿名內部類的初始代碼塊中,我們可以對外部類的任意成員變量,方法進行調用。大大便利我們書寫錄制腳本。

  1. 通過構建函數注入類/對象來錄制

    在上面的例子中,我們通過引用外部類的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());
     }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM