Mockito verify the last call on a mocked object

隐身守侯 提交于 2019-12-03 20:25:00

About the order of the invocations

By default, Mockito.verify() doesn't matter of the invocation order.
To take it into consideration, wrap the mock in an InOrder instance and perform the invocation verification on this instance.

About the no more interations

If the mock is no more invoked after the methods that you want to verify, you could use Mockito.verifyNoMoreInteractions(Object... mocks) that checks if any of given mocks has any unverified interaction such as :

InOrder inOrder = Mockito.inOrder(mockedA);
inOrder.verify(mockedA).add("1");
inOrder.verify(mockedA).add("2");
Mockito.verifyNoMoreInteractions(mockedA);

If the mock may still be invoked after the methods that you want to verify, you could add after your verifies an invocation to verify(T mock, VerificationMode mode) by passing a VerificationMode that checks that at most 2 invocations were performed.

InOrder inOrder = Mockito.inOrder(mockedA);
inOrder.verify(mockedA).add("1");
inOrder.verify(mockedA).add("2");
Mockito.verify(mockedA, Mockito.atMost(2)).add(Mockito.anyString());

A warning about your think and this way of mocking

Since the test above can't catch if somebody by accident adds another call such as add("3") in the last.

Mockito provides a powerful and broad toolkit to work with mocks. Some features such as verify and more particularly verify that no more interaction was detected about a mock or a specific method of the mock make your test more complex to read and to maintain.
As well as, currently you want to check that the invocations on a mock were performed in a specific order. But you generally want to use these checks only as required that is according to the business/logic scenarios, not technical invocations.
For example supposing that in the tested method you have a case where for business reasons the mocked method is invoked 3 times and another case where the mocked method is invoked 2 times. It could make sense to check that it is only invoked 2 times and not more in the case with two expected invocations.
But in a general way, you should be cautious that your unit test doesn't overuse mocking verify that could look like as a assertion on the description of the flow and not a assertion on the behavior/logic.

Thanks @staszko032, inspired by the ArgumentCaptor, instead of getAllValues and verify the sequence, we can use getValue of captor since captor's getValue always get the last true argument. We can do it like this:

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
    Mockito.verify(mockedA, Mockito.atLeastOnce()).add(captor.capture());
    Assert.assertEquals("2", captor.getValue());

What this looks like to me is that you are mocking a data class. In my experience it's better to leave (stateful) data classes and mock (stateless) services. This way, you can verify that the method under test produces the correct data, rather than just verifying a series of invocations. Along with testdata builders (making it easy to instantiate your data classes with some default state, using builder pattern for instance), it becomes real easy to write tests.

If you do need to mock, the only way to test what you want is to use InOrder, and verify each of the invocations on the mock, and end with verifyNoMoreInteractions.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!