2017-01-10 7 views
1

以下は、WorkWithArrayListのクラスの例です。このクラスには、2つのメソッドremoveFirstThreeinsertDataがあります。 removeFirstThreeメソッドは、引数としてListを取得し、それを変更してデータベースに挿入します。 forループでは、Listの最初の要素を取り除いているかのようにこの変更を示し、すべての反復でデータを挿入します。メソッドが期待された引数(引数として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); 
} 

は、このため、可変データのために、それはコピーしたデータは、(彼らが起こるとして、あるいはそれ以外のコールのそれぞれを検出)Answerに頼らずに正しい動作を実証するためMockitoを使用することは非常に難しいかもしれません。

2

私が本当に重要なことを逃していない限り、あなたは物を混ぜているので、物事をテストするのが難しくなります。

あなたが見る、はどこかにリスト2人の異なる責任あるを入れリストとを修正します。したがって、両方のアスペクトを同じクラスに強制すると、テストが難しくなります。

ここではより良いアプローチです。別の懸念事項です。リスト操作を行うクラスを作成します。そのクラスはおそらくを黙らせずにテストすることができます! リストを作成します。そのクラスにリストを与えます。何が戻ってくるか確認してください。ただ必要と主張する!

リスト操作が機能していることがわかったら、DBワークにリストを書き込むことだけをテストする必要があります。書き込むリストが実際にどのように見えるかは気にしません!

関連する問題