Mockito在同一NavigationSet上给出了无穷while循环和有限for循环


  • 我在JUnit测试中使用Mockito。我嘲笑了一个NavigableSet
  • 在我的单元测试中,在某个时刻,我需要循环到这个NavigableSet中包含的对象中
  • 出于测试目的,我计划这个NavigableSet只包含一个对象

以下是我使用Mockito创建mock对象的代码:

NavigableSet<ObjectToProcess> newMockedSet = new TreeSet<ObjectToProcess>();
ObjectToProcess mockedInnerObject = new ObjectToProcess(); // initialization of this object
newMockedSet.add(mockedInnerObject); // I just added the only 1 object contained in the NavigableSet
Mockito.when(getSetOfObjectToProcess()).thenReturn(newMockedSet);

为什么下面的while循环给出了一个NavigableSet只包含1个对象的无限循环?

NavigableSet<ObjectToProcess> anotherSetOfObjects = getSetOfObjectToProcess(); // retrieving the mocked object
while (anotherSetOfObjects.iterator().hasNext())
{
    ObjectToProcess thisPaymentDemand = anotherSetOfObjects.iterator().next();
    // do stuff
}

为什么下面的for循环只按预期循环一次?

NavigableSet<ObjectToProcess> anotherSetOfObjects = getSetOfObjectToProcess(); // retrieving the mocked object
for (ObjectToProcess thisMockedInnerObject : anotherSetOfObjects)
{
    ObjectToProcess thisPaymentDemand = thisMockedInnerObject;
    // do stuff
}

这不是Mockito的问题。

while示例中,您在EACH迭代的循环开始时调用anotherSetOfObjects.iterator()

您将获得一个迭代器(用于包含单个项的mockedSet),然后检查它是否有下一个(它有),然后输入循环的主体。主体完成后,您将再次运行条件检查,以查看是否循环。。。通过获得一个NEW迭代器,它的功能与第一个迭代器完全相同(假设您在此期间没有修改集合)。

将迭代器存储在循环之外,这样您就可以在每次迭代中测试相同的迭代器,而不是获得新迭代器:

Iterator<NavigableSet> iterator = anotherSetOfObjects.iterator();
while (iterator.hasNext())
{
    ObjectToProcess thisPaymentDemand = anotherSetOfObjects.iterator().next();
    // do stuff
}

这样做将使while循环的行为与for循环的行为相同。

从发布的代码中很难理解您的意图。您需要演示某个协作类类型的mock对象的创建以及正在测试的类的标识。此外,when()调用的参数应该是Mockito mock上方法调用的形式。换句话说,

// setting up test fixture
MyCollaborator x = Mockito.mock(MyCollaborator.class);
when(x.getSetOfObjectToProcess()).thenReturn(newMockedSet);
// and then later in test
NavigableSet<ObjectToProcess> anotherSetOfObjects = x.getSetOfObjectToProcess();
while(anotherSetOfObjects.iterator() ...) {
// or
for (ObjectToProcess thisMockedInnerObject : anotherSetOfObjects) {
... 

因此,您缺少when()参数的x.部分。

不太清楚的是你最初的意图是什么。如果您试图在某个类上测试方法getSetOfObjectToProcess(),那么您不应该嘲笑该类。您应该只嘲笑与您正在测试的类(通常称为"测试中的系统"或SUT)交互的合作者类/对象。

您的代码甚至没有显示使用Mockito.mock()方法或@Mock注释创建Mockito mock对象的情况,并且至少有一个是使用Mockito所必需的。如果getSetOfObjectToProcess()是一个静态方法,那么Mockito无论如何都不会为您模拟它。

相关内容

  • 没有找到相关文章

最新更新