gpt4 book ai didi

java - 模拟一个列表并尝试迭代它

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:35:41 26 4
gpt4 key购买 nike

目前正在使用 Mockito 测试我的一个类中的方法。我的类包含一个列表,并且该方法接受同一个类的对象。问题是当我尝试从对象迭代列表时。我得到一个指向列表的空指针。您将在下面看到代码片段。

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 测试,下面是我的类方法:

公共(public)类装运{

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){在 mergeShipemts() 中;

问题是;是否可以模拟一个列表,调用该列表,然后在该模拟列表上运行 foreach?

最佳答案

有一些基本问题导致您的示例无法正常工作并抛出 NullPointerException

  1. 对模拟列表上的 add() 的调用实际上没有做任何事情。默认情况下,mock 上的所有 void 方法都是“无操作”
  2. 在幕后使用 for-each 语法调用 Collection.iterator() 遍历列表。这将返回 null,因为您尚未设置 mockito 以返回任何其他内容。

相反,我不会模拟列表,而是传递一个实际列表。 Arrays.asList()方便测试。

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

如果你决定模拟一个列表,那么你必须模拟它的行为,即让 add() 实际上存储一些东西,而 .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);
}
}

关于java - 模拟一个列表并尝试迭代它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43067137/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com