A Decent Mockito.verify Example

I always get confused as to when it would be a good time to use verify. I also see verify thrown into tests for no reason at all, except maybe as a practice to remember the syntax. I had written a Spring validation class and a test, and since Errors is an interface and is more easily used in tests as a mock (IMHO) I thought it a good spot to do a verify for the test instead of the usual assertsEquals or whatever.

The rule is, for an object add, the objectId must be null or else I return a validation error.

The calling Spring (3.2) controller method:


@ApiOperation(value = “add new object”)

@RequestMapping(method = RequestMethod.PUT)

public
@ResponseBody

ObjectAdd add(@Valid
@RequestBody Object object) {

    return objectService.add(object);

}

Here’s my validation class. What it does is ensure there wasn’t an ID submitted to my PUT method – help the UI people out a little I know that get’s confusing. Also, if we make our rest API public this will help and . . it’s just good practice.

The test we’ll write is on this class, to confirm it is checking for a null ID value. We’ll confirm that the Error object method either get’s called, or doesn’t, depending on if the ID is null or not (remember we are in ADD mode so we do not want an ID).

@Component(“objectValidator”)

public
class ObjectValidator implements Validator {


@Value(“${object.Id}”)

private String idName;


@Value(“${object.add.empty.id}”)

private String idError;


@SuppressWarnings(“rawtypes”)


@Override

public
boolean supports(Class clazz) {

    return Object.class.isAssignableFrom(clazz);

}


@Override

    public
void validate(Object target, Errors errors) {

        Object object = (Object) target;

        if (null != object.getObjectId()) {

         errors.rejectValue(idName, idError);

        }

    }

}

Here’s the pojo, Jacksonfied because it comes in via a Controller and @Valid is used on the @Request:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)

@JsonTypeName(“object”)

public
class Object

{

    @JsonProperty

    private Integer objectId;

    @JsonProperty

    private String objectText;

    @JsonProperty

    private Date createDate;

    public Object()

    {

        // no-arg constructor for Jackson

    }

    public Integer getObjectId()

    {

        return objectId;

    }

    public
void setObjectId(Integer objectId)

    {

        this.objectId = objectId;

    }

    public String getObjectText()

    {

        return objectText;

    }

    public void setObjectText (String objectText)

    {

        this.objectText = objectText;

    }

    public Date getCreateDate()

    {

        return createDate;

    }

    public void setCreateDate(Date createDate)

    {

        this.createDate = createDate;

    }

}

And here’s my unit test with verification:

public
class ObjectValidatorTest {


@InjectMocks

private ObjectValidator objectValidator = new ObjectValidator();

@Mock

private Errors mockErrors;


@Before

public
void setUp() throws Exception {

    MockitoAnnotations.initMocks(this);

}


@After

public
void tearDown() throws Exception {

}


@Test

public
void testValidate() {

    Object object = new Object();

    object.setObjectId(null);

    objectValidator.validate(object, mockErrors);

    verify(mockErrors, times(0)).rejectValue(anyString(),anyString());

    

    object.setObjectId(44);

    objectValidator.validate(object, mockErrors);

    verify(mockErrors, times(1)).rejectValue(anyString(),anyString());

}


@Test

public
void testSupports() {

    assertTrue(objectValidator.supports(Object.class));

    assertFalse(objectValidator.supports(String.class));

}


I think this makes a lot of sense. We aren’t testing Errors itself, just if our validation methods logic calls Errors or ignores it in the correct situations.

One thing to force ourselves to really think about when writing mock tests is “what are we really testing.” A lot of times I get errors, forgetting “ah, yeah even that service had to be mocked.” Verification can help us test our class that has a mock component.

Comments are closed.