mockito验证多态方法

时间:2015-10-24 18:46:21

标签: java mockito

我正在尝试使用mockito来验证对多态方法的调用,并且对前进的最佳方式感到困惑。

示例类

$('.upvote .vote').on('click', function (e) {
    e.preventDefault();
    $('a.upvote').removeClass('upvote-on');
    $('span.count').val(parseInt($('span.count').val()) - 1);
});

$('.downvote .vote').on('click', function (e) {
    e.preventDefault();
    $('a.downvote').removeClass('downvote-on');
    $(".count").text(Number($(".count").text()) + 1);
});

使用mockito的测试类(忽略public class Library { public boolean foo() { return true; } public boolean foo(String s) { return true; } public boolean foo(Integer s) { return true; } } 类中的事实,LibraryTest不是被测试的类,而是我在嘲笑它)

Library

因此两个verify语句都没有编译,错误“方法foo(String)对于类型库来说是不明确的。”

错误类型有意义,import org.junit.Test; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class LibraryTest { @Test public void testFoo1() { Library mockLibrary = mock(Library.class); mockLibrary.foo("Hi"); verify(mockLibrary).foo(any()); } @Test public void testFoo2() { Library mockLibrary = mock(Library.class); verify(mockLibrary, never()).foo(any()); } } 尝试根据参数的类型返回捕获者,但参数可以是any()IntegerString

我想要实现的是,在两个测试中,void计算对任何foo方法的调用。换句话说,如果我调用任何verify方法,第一个verify调用应该会成功,如果我调用任何foo方法,则第二个verify会失败。

有没有办法让这种情况发生?

2 个答案:

答案 0 :(得分:4)

您可以使用isA matcher

verify(mockLibrary).foo(isA(Integer.class));

verify(mockLibrary).foo(isA(String.class));

并且btw使用Mockito.spy代替Mockito.mock,当你只想看看是否已经在被测试的类上调用了一些方法

根据新的操作细节编辑(以几分钟编写,不要介意代码:))。

public static class Library {
    public boolean foo() {
        return true;
    }

    public boolean foo(String s) {
        return true;
    }

    public boolean foo(Integer s) {
        return true;
    }

    public String x(){
        return "";
    }

    public void y(){
        return;
    }
}


public static class ResponseProvider {
    public boolean result;
}

@Test
public void testFoo1() {
    final ResponseProvider provider = new ResponseProvider();
    provider.result = false;
    Library lib = Mockito.mock(Library.class, new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            if ((invocation.getMethod().getName().equals("foo"))) {
                provider.result = true;
                return true;
            }
            return invocation.callRealMethod();
        }
    });

    //lib.foo();
    //lib.x();
    //lib.y();
    assertTrue(provider.result);

}

答案 1 :(得分:1)

首先,您正在模拟您正在测试的同一个类。这不是可取的,但仍然

它给出了这个例外,因为mockito不知道你在foo方法中验证哪种方法。如果要确保使用正确的值调用所调用的方法,可以使用isA(ClassName)匹配器或使用可以使用ArgumentCaptor。

ArgumentCaptor的示例

@Test public void testFoo1() {
    Library mockLibrary = mock(Library.class);
    mockLibrary.foo("Hi");
    ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);

    verify(mockLibrary).foo(stringCaptor.capture());
    String actualArgument = stringCaptor.getValue();

    assertEquals(actualArgument, "Hi");
}