2017-01-10 45 views
1

下面您可以看到一個示例類WorkWithArrayList。本課程有兩種方法removeFirstThreeinsertDataremoveFirstThree方法獲取List作爲參數並對其進行修改並插入到數據庫中。在for循環中,我展示了此修改,就好像它正在刪除IntegerList的第一個元素,並在每次迭代中插入數據。如何通過Mockito驗證方法是否以期望的參數(java.util.List作爲參數)調用

我想要實現的是驗證insertData方法的參數。但verify方法檢查只有第一個verify(workWithArrayList).insertData(expected);聲明。

package test; 

import org.junit.Before; 
import org.junit.Test; 

import java.util.ArrayList; 
import java.util.List; 

import static org.mockito.Mockito.spy; 
import static org.mockito.Mockito.verify; 

public class MockitoVerifyWithArrayListTest { 

    private WorkWithArrayList workWithArrayList; 
    private List<Integer> actual; 
    private List<Integer> expected; 

    @Before 
    public void setUp() throws Exception { 

     workWithArrayList = spy(new WorkWithArrayList()); 

     actual = new ArrayList<>(); 
     actual.add(1); 
     actual.add(2); 
     actual.add(3); 
     actual.add(4); 
     actual.add(5); 
     actual.add(6); 

     expected = new ArrayList<>(); 
     expected.add(1); 
     expected.add(2); 
     expected.add(3); 
     expected.add(4); 
     expected.add(5); 
     expected.add(6); 
    } 

    @Test 
    public void test() throws Exception { 

     workWithArrayList.removeFirstThree(actual); 

     expected.remove(0); 
     verify(workWithArrayList).insertData(expected); 

     expected.remove(0); 
     verify(workWithArrayList).insertData(expected); 

     expected.remove(0); 
     verify(workWithArrayList).insertData(expected); 
    } 

    public class WorkWithArrayList { 

     public void removeFirstThree(List<Integer> integers) { 

      for (int i = 0; i < 3; i++) { 

       integers.remove(0); 
       insertData(integers); 
      } 
     } 

     public void insertData(List<Integer> integers) { 

     } 
    } 
} 

當我運行這個測試,我用下面的錯誤面向:

Argument(s) are different! Wanted: 
workWithArrayList.insertData(
    [2, 3, 4, 5, 6] 
); 
-> at test.MockitoVerifyWithArrayListTest.test(MockitoVerifyWithArrayListTest.java:46) 
Actual invocation has different arguments: 
workWithArrayList.insertData(
    [4, 5, 6] 
); 
-> at test.MockitoVerifyWithArrayListTest.test(MockitoVerifyWithArrayListTest.java:43) 

編輯:如果我們看一下Mockito.verify方法的javadoc,我們可以看到這一點:
參數傳遞的比較採用equals()方法。

但變量actualexpected是相等的,即使我們刪除了第一個元素,它們也會保持相等。我很感興趣,爲什麼這個測試失敗了。

回答

1

Mockito在存儲調用細節或採取任何形式的「快照」時不克隆或複製對象;該值被傳入,Mockito複製參考。這意味着匹配一個真正的可變對象可能是非常不直觀的。

@Test 
public void test() throws Exception { 
    // expected: [1, 2, 3, 4, 5, 6]; actual: [1, 2, 3, 4, 5, 6]; 

    workWithArrayList.removeFirstThree(actual); 

    // expected: [1, 2, 3, 4, 5, 6]; actual: [4, 5, 6] 
    // Mockito's invocation list: 
    // three calls to removeFirstThree(actual), where actual is [4, 5, 6], 
    // even though actual had different values during each of the calls! 

    expected.remove(0); 
    verify(workWithArrayList).insertData(expected); 

    expected.remove(0); 
    verify(workWithArrayList).insertData(expected); 

    expected.remove(0); 
    verify(workWithArrayList).insertData(expected); 
} 

由於這種可變數據的,它可能是很難使用到的Mockito展示正確的行爲無需求助於Answer是將數據複製(或以其他方式檢測每個呼叫的,因爲它們發生)。

2

除非我錯過了一些非常重要的東西,否則你會混淆東西,從而使自己難以測試。

你看,修改列表,並把某處列出兩種不同責任。因此,你強迫這兩個方面進入同一個班級使測試變得困難!

這裏有一個更好的方法:單獨關注。創建一個沒有列表操作的類。那個班可以在沒有任何嘲笑的情況下進行測試! 您創建一個列表;給列表修改類;並檢查返回的內容。只是斷言需要!

然後,當你知道列表操作起作用時,你只需要測試寫一個列表到DB的作品;而且你不在乎如何編寫列表實際上看起來像!

相關問題