Mockito验证抛出UnfinishedVerificationException

时间:2018-04-05 08:42:35

标签: java unit-testing mockito junit4

在测试中,我使用的是模拟对象:

@Mock
ListMultipleChoice<String> listMultipleChoiceMock;

我尝试验证其方法的使用:

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

但它引发了以下异常:

  

org.mockito.exceptions.misusing.UnfinishedVerificationException:   缺少方法调用验证(模拟):

此行的例外情况:

verify(listMultipleChoiceMock).setMaxRows(2);

setMaxRows接受一个int。

当我评论此行时,测试成功。当我调试我的程序时,我可以看到设置setMaxRows的方法:

brandsListMultipleChoice.setMaxRows(brandLabels.size());

brandLabels是List,size()返回一个int。

我检查了brandLabels的大小,它是2.我已经尝试过anyInt()和0,两者都会导致抛出异常。

我做错了什么?为什么这个验证没有成功?

以下是我的代码示例,该代码将失败:

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());

    }
}

正在测试的课程:

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() {
            }
        });
    }
}

当我注释掉第二个或第三个验证规则时,测试成功。

2 个答案:

答案 0 :(得分:0)

我尝试编写简单的测试:

public class ListMultipleChoiceTest {
    public class ListMultipleChoice<T>{
        public void setMaxRows(int maxRows) {
        }
    }

    @Mock
    ListMultipleChoice<String> listMultipleChoiceMock;

    @Test
    public void testSetMaxRows() {
        verify(listMultipleChoiceMock, never()).setMaxRows(2);
        listMultipleChoiceMock.setMaxRows(2);
        verify(listMultipleChoiceMock).setMaxRows(2);
    }
}

它成功通过。 您应该仔细检查您的课程用法。 或者提供更多代码示例。

答案 1 :(得分:0)

显然无法模拟最终方法。

解决这个问题的方法是将模拟类添加到注释@PrepareForTest(ListMultipleChoice.class)

通过这种方式,PowerMockito将处理模拟对象。