Main menu

Post navigation

Mockito: Verifying Details of an Object Passed to a Collaborator

Recently I was BDD’ing a class, and the behavior I needed to describe happened to be an object created internally (a simple value object) populated with a few attributes and passed to a collaborator. The old way I might be tempted to do this is just create a concrete implementation of the collaborator that stores the argument passed to it, then get it back and verify some outcome on it.

But I wondered if there was a way to do it with Mockito without it looking crappy. And apparently there is a way to verify values on an argument to a collaborator using ArgumentCaptor.

First, let’s create a rather contrived example for illustration. Say we have some kind of application where we have a method that adds users to some kind of CMS. Now lets also assume we have some kind of event mechanism in place and we want to fire a USER_ADDED event with the User that was added attached to it so that handlers can respond to this event. Essentially, we want to ensure that the collaborator (in this case the EventPublisher) receives an Event with certain attributes that it should have.

I will say, I’m not too fond of the forced verify call to capture the argument as it creates a bit of noise! To get this mess to compile before we pass the example, we first create the object and it’s signatures:

Awesome, it passes! Now lets step back over the example line by line so we can illustrate what is going on here (because I know the ArgumentCaptor’s syntax confused me in the documentation):

ArgumentCaptor argument = ArgumentCaptor.forClass(Event.class);

This is the factory method to create an instance of the argument captor for the Event type. I’ve named it argument so that it reads better later (as I will explain). Nothing special here… just creating the instance for use in the example.

verify(publisher).publish(argument.capture());

Here, we’re using the ArgumentCaptor to capture the argument that gets passed to the publish invocation. As you can see, the naming pays off as it reads like it’s capturing the argument (which IS what it is doing after all). The way it works is it has already captured the arguments of any methods called on the mock (thanks to proxying) and stored them for access… but by calling the capture method in this way it sets the argument being “looked at” to the one that was passed to the publish method. Whew!

assertEquals(EventType.USER_ADDED, argument.getValue().getType());

Nothing special here… getValue() simply returns the argument that was captured, in this case the Event that was published.

Hope this helps you like it helped me… before I figured this out, I was copping out and was creating a hard coded mock of the EventPublisher… adding a bit of ugly looking code to the specification. That always feel repetitive.