Search code examples
javaunit-testingmockitojunit4

Mockito verify throws UnfinishedVerificationException


In a test, I am using a mockobject:

@Mock
ListMultipleChoice<String> listMultipleChoiceMock;

I try to verify the use of its methods:

verify(listMultipleChoiceMock).setRequired(true);
verify(listMultipleChoiceMock).setMaxRows(2);
verify(listMultipleChoiceMock).setDefaultModel(any(IModel.class));

But it throws the following exception:

org.mockito.exceptions.misusing.UnfinishedVerificationException: Missing method call for verify(mock) here:

The exception points at this line:

verify(listMultipleChoiceMock).setMaxRows(2);

setMaxRows accepts an int.

When I comment this line out, the test succeeds. When I debug my program, I can see the method setMaxRows being set:

brandsListMultipleChoice.setMaxRows(brandLabels.size());

brandLabels is a List and size() returns an int.

I check the size of brandLabels and it is 2. I have tried anyInt() and 0 as well, both result in an exception being thrown.

What am I doing wrong? Why is this verification not succeeding?

Here is an example of my code, which will fail:

import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Example.class})
public class ExampleTest {

    @Mock
    ListMultipleChoice<String> brandsListMultipleChoiceMock;

    @Before
    public void setUp() throws Exception {
        whenNew(ListMultipleChoice.class).withAnyArguments().thenReturn(brandsListMultipleChoiceMock);

        Example example = new Example();
    }

    @Test
    public void test() throws Exception {
        verify(brandsListMultipleChoiceMock).setRequired(true);
        verify(brandsListMultipleChoiceMock).setMaxRows(1);
        verify(brandsListMultipleChoiceMock).setDefaultModel(anyObject());

    }
}

And the class being tested:

import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Example {

    private ListMultipleChoice<String> brandsListMultipleChoice;

    public Example() {

        List<String> brandLabels = new ArrayList<>();
        brandLabels.add("DEMO");

        brandsListMultipleChoice = new ListMultipleChoice<>("brands", new PropertyModel<Set<String>>(this, "brandProperty"), brandLabels);
        brandsListMultipleChoice.setRequired(true);
        brandsListMultipleChoice.setMaxRows(brandLabels.size());
        brandsListMultipleChoice.setDefaultModel(new IModel<Set<String>>() {
            private Set<String> list = new HashSet<>();

            @Override
            public Set<String> getObject() {
                return list;
            }

            @Override
            public void setObject(Set<String> ts) {
                list = ts;
            }

            @Override
            public void detach() {
            }
        });
    }
}

When I comment out either the second or the third verify rule, the test succeeds.


Solution

  • Apparently it is not possible to mock final methods.

    The sollution to this problem is adding the mocked class to the annotation @PrepareForTest(ListMultipleChoice.class)

    In this way PowerMockito will handle the mocked object.