2017-03-28 9 views
2

現在、Mockitoを使って自分のクラスのメソッドをテストしています。私のクラスはListを持ち、このメソッドは同じクラスのオブジェクトを取ります。問題は、オブジェクトからリストを反復しようとするときです。私はリストにnullポインタを取得しています。下にコードスニペットが表示されます。リストをモックして、それを反復しようとしています

private Shipment shipment; 
private Shipment shipment2; 
@Mock 
private Order mockOrder1; 
@Mock 
private Order mockOrder2; 
@Mock 
private Order mockOrder3; 
@Mock 
private ArrayList<Order> mockShipmentOrders; 
@Mock 
private ArrayList<Order> mockShipmentOrders2; 

@Before 
public void setUp(){ 
    MockitoAnnotations.initMocks(this); 
    mockShipmentOrders.add(mockOrder1); 
    mockShipmentOrders.add(mockOrder2); 
    mockShipmentOrders2.add(mockOrder3); 
    shipment = new Shipment(1, mockShipmentOrders); 
    shipment2 = new Shipment(2, mockShipmentOrders2); 
} 

@Test 
public void test_mergeShipments_increasesByOneWhenAShipmentOfOneAddedToAShipmentORderSizeOfTwo(){ 
    shipment.mergeShipments(shipment2); 
    assertEquals(3, shipment.getShipmentOrders().size()); 
} 

あなたは私のmockitoテストを参照して、以下の方法で私のクラスであることができ、上記:

パブリッククラス出荷{

private long shipmentID; 
private List<Order> shipmentOrders; 

public Shipment(long shipmentID, List<Order> shipmentOrders){ 
    this.shipmentID = shipmentID; 
    this.shipmentOrders = shipmentOrders; 
} 

public List<Order> getShipmentOrders(){ 
    return shipmentOrders; 
} 

public void mergeShipments(Shipment shipment2){  
    List<Order> existingShipment = shipment2.getShipmentOrders(); 
    for (Order order : existingShipment){ 
     shipmentOrders.add(order); 
    } 
} 

を私はjava.langのを取得していますテストを実行すると行のための.NullPointerException:for(Order order:existingShipment){ in mergeShipemts();

質問は次のとおりです。リストを模擬し、そのリストを呼び出して、その模擬リストを使ってforeachを実行することは可能ですか?

+0

なぜあなたはリストを模擬する必要がありますか? –

答えて

2

あなたの例がうまく動作せず、NullPointerExceptionをスローする根本的な問題がいくつかあります。

  1. 模擬リストのadd()への呼び出しは実質的に何もしません。モックのすべてのvoidメソッドは、デフォルトでは "no-ops"です
  2. フードの下にそれぞれの構文呼び出しCollection.iterator()を使用してリストを反復処理します。これは、あなたが何かを返すようにmockitoを設定していないので、nullを返します。

代わりに、私はリストを模擬しないで、代わりに実際のリストを渡します。 Arrays.asList()はテストに便利です。

@Before 
public void setUp(){ 
    MockitoAnnotations.initMocks(this); 
    shipment = new Shipment(1, Arrays.asList(mockOrder1, mockOrder2)); 
    shipment2 = new Shipment(2, Arrays.asList(mockOrder3)); 
} 

リストを模擬するために決定されている場合、あなたはすなわちアドオンを(作り、その動作を模擬する必要がありますが)実際に何かと.iterator()イテレータを返すを格納します。これは次のようにかなり痛ましいことがあります。私は原則を実証するためにこれだけを含んでいます。

@Mock 
private List<String> mockedList; 

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 

    List<String> realList = new ArrayList<>(); 
    doAnswer(new Answer<String>() { 
     @Override 
     public String answer(InvocationOnMock invocation) throws Throwable { 
      realList.add(invocation.getArgumentAt(0, String.class)); 
      return null; 
     } 

    }).when(mockedList).add(any()); 

    when(mockedList.iterator()).thenAnswer(new Answer<Iterator<String>>() { 

     @Override 
     public Iterator<String> answer(InvocationOnMock invocation) throws Throwable { 
      return realList.iterator(); 
     } 
    }); 

    mockedList.add("bar"); 
    mockedList.add("baz"); 
} 

@Test 
public void iterateOverMockedList() { 
    for (String each : mockedList) { 
     System.out.println(each); 
    } 
} 
+0

ご連絡ありがとうございます。リストを嘲笑するのはむしろ難しいと思っていました。そして、私のMockitoの理解は、すべてを模倣することでした。私はarraylistsから '@mock'を削除して初期化し、テストに合格しました。 リストを模擬することがどれほど複雑かをあなたの説明のためにありがとう。 –

0

Mocked要素に値を追加することはできません。 @Mockをデータのリストから削除し、新しいキーワードを使用して初期化することができます。

private Shipment shipment; 
private Shipment shipment2; 
@Mock 
private Order mockOrder1; 
@Mock 
private Order mockOrder2; 
@Mock 
private Order mockOrder3; 

private ArrayList<Order> mockShipmentOrders; 

private ArrayList<Order> mockShipmentOrders2; 

@Before 
public void setUp(){ 
    MockitoAnnotations.initMocks(this); 
    mockShipmentOrders = new ArrayList<>(); 
    mockShipmentOrders2 = new ArrayList<>(); 
    mockShipmentOrders.add(mockOrder1); 
    mockShipmentOrders.add(mockOrder2); 
    mockShipmentOrders2.add(mockOrder3); 
    shipment = new Shipment(1, mockShipmentOrders); 
    shipment2 = new Shipment(2, mockShipmentOrders2); 
} 

@Test 
public void test_mergeShipments_increasesByOneWhenAShipmentOfOneAddedToAShipmentORderSizeOfTwo(){ 
    System.out.println(shipment); 
    System.out.println(shipment2); 
    shipment.mergeShipments(shipment2); 

    assertEquals(3, shipment.getShipmentOrders().size()); 
} 
関連する問題