51

我正在使用 Mockito 在 Java 中编写单元测试,并且我想验证某个方法是否是对象上调用的最后一个方法。

我在被测代码中做这样的事情:

row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();

在我的模拟中,我不关心编辑行中所有内容的顺序,但重要的是我在保存后不要尝试对其进行任何操作。有没有好的方法来做到这一点?

请注意,我不是在寻找 verifyNoMoreInteractions:它不确认 saveToDatabase 是最后一个调用的东西,如果我在行上调用任何我没有明确验证的东西,它也会失败。我希望能够这样说:

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();

如果有帮助,我将从执行此操作的 JMock 测试切换到 Mockito:

row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");
4

3 回答 3

59

我认为这需要更多的定制工作。

verify(row, new LastCall()).saveToDatabase();

进而

public class LastCall implements VerificationMode {
    public void verify(VerificationData data) {
        List<Invocation> invocations = data.getAllInvocations();
        InvocationMatcher matcher = data.getWanted();
        Invocation invocation = invocations.get(invocations.size() - 1);
        if (!matcher.matches(invocation)) throw new MockitoException("...");
    }
}

上一个答案:

你说的对。verifyNoMoreInteractions 是您所需要的。

verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);
于 2009-02-05T03:43:07.383 回答
12

不是 100% 的主题,但我只是想找到验证的反面,这是唯一相关的结果,最终我在 Mockito.verifyZeroInteractions(mock);

以防万一其他人最终在这里寻找这个......

于 2011-01-27T14:20:00.370 回答
1

这个问题促使我对JMockit中的Verifications API进行了一些增强(在即将发布的 0.983 版本中提供)。

我提出的解决方案允许您编写(在测试方法中):


    new VerificationsInOrder() {{
        unverifiedInvocations();
        row.saveToDababase();
    }};

...如果您只想验证某个方法是否在其他所有操作之后被调用。要验证它在所有其他调用之前发生,只需将调用移至顶部。这实际上适用于任何连续调用序列。

如果除了上述验证之外,您还想验证是否以任意顺序调用了其他一些方法,则可以在测试中添加第二个验证块(在另一个块之前或之后,没关系):


    new Verifications() {{
        row.setSomething(value);
        row.setSomethingElse(anotherValue);
    }};

虽然因为使用匿名内部类有点长,但这种语法既简单又灵活;注意它如何为测试添加结构并避免方法调用的重复(如verify(...))。它比我在这里描述的要多(Hamcrest 匹配器、调用计数等),而且它不限于实例方法的验证(静态方法和构造函数可以以相同的方式进行模拟和验证)。

于 2009-06-29T00:01:47.540 回答