Creating a custom VerificationMode classes for Mockito

Geo

I would like to verify some things using Mockito but studying the documentation has lead me to believe that it's not possible without going outside the usual Mockito tools. Take this for an example:

DrawTool tool = mock(DrawTool.class);
new Drawer().draw(tool);
verify(tool).begin(); // Make sure begin and end are called exactly once each
verify(tool).end();
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();
inOrder.verifyNoMoreInteractions();

This test verifies several things well, such as verifying that flush is the last interaction, but it seems that Mockito has no way to verify that begin is the first interaction. I'm surprised by that asymmetry in Mockito's tools and so I'm investigating the possibility of creating custom VerificationModes. I'd like to create a VerificationMode called something like beforeAnyOther and use it like this:

inOrder.verify(tool, beforeAnyOther()).begin();
inOrder.verify(tool).end();
inOrder.verify(tool, beforeAnyOther()).flush();
inOrder.verifyNoMoreInteractions();

The intent would be to verify that begin is called first and that there are no relevant interactions between end and flush while leaving the interactions between begin and end unspecified.

I have been studying the source code for the existing VerificationModes and it seems that in principle this should be a simple VerificationMode to implement, but once I get beyond a few of Mockito's major classes the documentation becomes very thin, almost like it's trying to tell me that I shouldn't be touching these classes. I'm especially wary of the packages that start org.mockito.internal because a name like that suggests to me that these classes are subject to change even though they are public.

The really important classes for implementing a VerificationMode seem to be all in the org.mockito.internal.verification.api package. That entire package seems to have only one bit of javadoc, and it says, "This package should be open to public once verification API is fully finished." Does that mean that this package is being actively modified and so I shouldn't use anything it contains, or is that just something that it has said for years and the package will probably never actually change?

If I can't use the classes in org.mockito.internal.verification.api then it seems it is impossible to implement custom VerificationModes. Is there a way to do things like this without custom VerificationModes?

pobrelkey

If you can fully specify the sequence of calls that will happen on your mock, then you won't need a beforeAnyOther verification mode. For example, assuming your desired behavior is...

  • begin gets called once, then
  • end gets called once, then
  • flush gets called once
  • no other calls are made on tool

then the following should the job:

// Verify that the three invocations arrived in the desired order.
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();

// Verify that the three invocations are all we received.
Mockito.verify(tool).begin();
Mockito.verify(tool).end();
Mockito.verify(tool).flush();
Mockito.verifyNoMoreInteractions();

On the other hand, if you have any additional calls that happen outside of the sequence you wish to verify then you're correct, Mockito can't verify that at present. So for example, if you knew you had to call tool.setPenColor() at some point between begin and flush but it didn't matter if this call came before or after the call to end, you'd be out of luck.

You can handle this situation in some other mocking libraries. EasyMock makes this easiest - for example, for a sequence where begin comes first, flush comes last, and we don't care about the calls in the middle:

DrawTool mock = EasyMock.createMock(DrawTool.class);
EasyMock.checkOrder(mock, true);
mock.begin();
EasyMock.expectLastCall();
EasyMock.checkOrder(mock, false);
mock.end();
EasyMock.expectLastCall();
EasyMock.expect(mock.someOtherCallThatReturnsAValue()).andReturn(null);
EasyMock.checkOrder(mock, true);
mock.flush();
EasyMock.expectLastCall();
EasyMock.replay(mock);

new Drawer().draw(tool);

EasyMock.verify(mock); 

An equivalent test appears to be possible, if unwieldy, in JMock 2. It's a bit easier in JMock 1, but that library is antiquated (circa JDK 1.3), so don't use it. This isn't possible in Moxie (disclaimer/shameless plug: I'm the author), but there's now a todo list item for that.

I can't speak for the Mockito devs as to why the Mockito verification API docs are the way they are - best ask them on the mailing list. I'm sure they'd welcome a patch.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Creating a custom VerificationMode classes for Mockito

From Dev

Creating custom Object classes android

From Dev

Creating classes

From Dev

Custom Classes and Collection Classes

From Dev

Creating a thread with a Mockito mocked Runnable

From Dev

Creating a Serializable mock with Mockito error

From Dev

Mockito with static methods in util classes

From Dev

Mockito with static methods in util classes

From Dev

How to avoid creating custom exception classes whilst still throwing exceptions at an appropriate level of abstraction?

From Dev

Xcode Help : Unspecific error codes when creating custom classes in objective-c

From Dev

Creating and Using Classes

From Dev

Creating model classes in TypeScript

From Dev

Creating a set of Python classes

From Dev

Creating classes by user of the program

From Dev

Creating an array of classes in Java

From Dev

Creating Methods and Classes (Java)

From Dev

Creating and using classes with canvas

From Dev

Creating objects with multiple classes

From Dev

Creating Methods in Separate Classes

From Dev

Creating a set of Python classes

From Dev

Creating Classes and Outputting

From Dev

Creating mock with Mockito for class that extends generic class

From Dev

C++ Abstract classes and creating derived classes

From Dev

Mocking an abstract class and injecting classes with Mockito annotations?

From Dev

How to use real classes and mockito at the same time?

From Dev

Creating Custom Objects in AngularJS

From Dev

Creating custom helper class?

From Dev

Creating a custom Bound Property

From Java

Creating an array of a custom class