是否有可能与Mockito进行严格的嘲笑?

时间:2011-11-03 23:36:26

标签: java unit-testing testing mocking mockito

我想使用严格的模拟,至少在第一次开发一些针对旧代码的测试时,所以如果我没有专门定义期望,那么在我的模拟上调用的任何方法都会抛出异常。

从我看到的情况来看,如果我没有定义任何期望,Mockito将只返回null,稍后会在其他地方导致NullPointerException。

有可能吗?如果是,怎么样?

6 个答案:

答案 0 :(得分:15)

你想要它做什么?

您可以将其设置为RETURN_SMART_NULLS,这样可以避免NPE并包含一些有用的信息。

您可以将其替换为自定义实现,例如,从其answer方法引发异常:

@Test
public void test() {
    Object mock = Mockito.mock(Object.class, new NullPointerExceptionAnswer());
    String s = mock.toString(); // Breaks here, as intended.
    assertEquals("", s);
}

class NullPointerExceptionAnswer<T> implements Answer<T> {
    @Override
    public T answer(InvocationOnMock invocation) throws Throwable {
        throw new NullPointerException();
    }
}

答案 1 :(得分:8)

您可以使用verifyNoMoreInteractions。如果测试类捕获异常,它会很有用。

@Test
public void testVerifyNoMoreInteractions() throws Exception {
    final MyInterface mock = Mockito.mock(MyInterface.class);

    new MyObject().doSomething(mock);

    verifyNoMoreInteractions(mock); // throws exception
}

private static class MyObject {
    public void doSomething(final MyInterface myInterface) {
        try {
            myInterface.doSomethingElse();
        } catch (Exception e) {
            // ignored
        }
    }
}

private static interface MyInterface {
    void doSomethingElse();
}

结果:

org.mockito.exceptions.verification.NoInteractionsWanted: 
No interactions wanted here:
-> at hu.palacsint.CatchTest.testVerifyNoMoreInteractions(CatchTest.java:18)
But found this interaction:
-> at hu.palacsint.CatchTest$MyObject.doSomething(CatchTest.java:24)
Actually, above is the only interaction with this mock.
    at hu.palacsint.stackoverflow.y2013.q8003278.CatchTest.testVerifyNoMoreInteractions(CatchTest.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    ...

答案 2 :(得分:5)

将此@Rule作为公共字段添加到您的测试类中:

@RunWith(JUnitParamsRunner.class)
public class MyClassTests {

    @Rule
    public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);

    @Test
    ....
}

此值已添加到版本2.3.0

中的Mockito

来自文档:

  

确保清洁测试,减少测试代码重复,改进   可调试。提供灵活性和最佳组合   生产率。强烈推荐。计划为Mockito v3的默认设置。   添加以下行为:

     
      
  • 提高工作效率:当测试代码时,测试会提前失败   使用不同的参数调用stubbed方法(请参阅   PotentialStubbingProblem)。
  •   
  • 清洁测试没有必要   stubbings:当存在未使用的存根时,测试失败(参见   UnnecessaryStubbingException)。
  •   
  • 清洁,更多干燥测试(&#34;不要重复   你自己&#34;):如果你使用Mockito.verifyNoMoreInteractions(对象...)你   不再需要显式验证存根调用。他们是   自动为您验证。
  •   

答案 3 :(得分:1)

除了MockitoRule方法之外,如果您不需要使用特定的测试运行程序(并且您正在使用Mockito 2.5.1或更高版本),则还可以考虑使用MockitoJUnitRunner.StrictStubs跑步者,即

@RunWith(MockitoJUnitRunner.StrictStubs.class)

(我会在有关MockitoRule的帖子中发表评论,但还没有这种能力)

答案 4 :(得分:0)

根据org.mockito.Mockito.RETURNS_DEFAULTS的源代码,它从全局设置中选择“如果没有期望该怎么办”。 此外“如果没有全局配置,那么它使用{@link ReturnsEmptyValues}(返回零,空集合,空值等)” 我还没有能够进行这种配置。

答案 5 :(得分:0)

下面的方法无法验证未调用的意外方法:

org.mockito.Mockito#only
org.mockito.Mockito#verifyNoMoreInteractions