Java 当我试图部分模拟一个void方法时,我得到了NotMockException——我做错了什么?

Java 当我试图部分模拟一个void方法时,我得到了NotMockException——我做错了什么?,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,我尝试同时使用两种Mockito模式: 对于部分模拟,请使用Mockito.spy 对于返回void的mocking方法,请使用Mockito.doXXX(…).when(mock.method(matchers),因为您不能使用Mockito.when(mock.method(matchers))语法,原因很明显(方法返回void,因此不能作为参数传递) 当组合它们时,我面临一个notomockexception。下面是一个(人为的)示例,我使用PowerMockito 1.6.2(=Mo

我尝试同时使用两种Mockito模式:

  • 对于部分模拟,请使用
    Mockito.spy
  • 对于返回void的mocking方法,请使用
    Mockito.doXXX(…).when(mock.method(matchers)
    ,因为您不能使用
    Mockito.when(mock.method(matchers))
    语法,原因很明显(
    方法
    返回void,因此不能作为参数传递)
当组合它们时,我面临一个
notomockexception
。下面是一个(人为的)示例,我使用PowerMockito 1.6.2(=Mockito 1.10.19)和JUnit 4.12对其进行了测试,并重现了这个问题

public class Greeter { // this is the class we will be partially mocking
    public void helloWorld(String hello, Set<String> set) {
        set.add("Hello: "+hello);
    }

    public void goodbyeWorld(String goodbye, Set<String> set) {
        set.add("Goodbye: "+goodbye);
    }
}

public class ExampleClass { // this is the class under test
    public String helloGoodbye(String input, Greeter greeter) {
        Set<String> helloSet = new HashSet<String>();
        Set<String> goodbyeSet = new HashSet<String>();
        greeter.helloWorld(input, helloSet);
        greeter.goodbyeWorld(input, goodbyeSet);
        return (helloSet.iterator().next() + ", " + goodbyeSet.iterator().next());
    }
}

public class ExampleClassTest {
    @Test
    public void test() {
        Greeter greeter = new Greeter();
        Mockito.spy(greeter);
        Mockito.doAnswer(new Answer(){ // exception thrown points to this line
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                ((Set<String>)invocation.getArguments()[1]).add("Bonjour: " + invocation.getArguments()[0]);
                return null;
            }
        }).when(greeter).helloWorld(Mockito.any(String.class), Mockito.any(Set.class));

        ExampleClass example = new ExampleClass();
        String aggregateGreeting = example.helloGoodbye("Mars", greeter);
        Assert.assertEquals("Bonjour: Mars, Goodbye: Mars", aggregateGreeting);
    }
}

任何变通方法(实现在类中模拟单个void方法的其他方法)都是受欢迎的

您没有将间谍传递给
when()
。您正在传递原始对象

换线

Mockito.spy(greeter);


Mockito.spy()
创建一个spy对象,它是原始对象的副本。它不会修改原始对象。

Wow!太简单了!谢谢:):)它甚至不是代表,阿飞;这是一个现场副本。所以原版的状态变化不会在间谍中显示,更不用说存根和验证了。
Mockito.spy(greeter);
greeter = Mockito.spy(greeter);