2015-12-21 105 views
0

我在我的JUnit测试中使用Mockito。测试是一个集成测试,测试整个场景,因此有很多断言和verify(mock) s。mockito“verify”检查当前状态,但不重置模拟调用

我的问题是,我正在写一些生产代码,做一些断言,然后验证它的工作模式,直到出现相同的模拟调用。看简化代码:

interface I { 
    void m1(); 
    void m2(); 
} 

// some decorator 
class T implements I { 
    public T(I decorated) { 
     /*...*/ 
    } 

    /* ... */ 
} 

public void testInvalid() { 
    I m = mock(I.class); 
    T t = new T(m); 

    t.m1(); 
    assertEquals("m1", t.getLastMethod()); 
    verify(m).m1(); 

    t.m2(); 
    assertEquals("m2", t.getLastMethod()); 
    verify(m).m2(); 

    t.m1(); 
    assertEquals("m1", t.getLastMethod()); 
    verify(m).m1(); 

    // TooManyActualInvocations t.m1(): Wanted 1 time, but was 2 times ... 
} 

public void testValid() { 
    I m = mock(I.class); 
    T t = new T(m); 

    t.m1(); 
    assertEquals("m1", t.getLastMethod()); 

    t.m2(); 
    assertEquals("m2", t.getLastMethod()); 

    t.m1(); 
    assertEquals("m1", t.getLastMethod()); 

    verify(m, times(2)).m1(); 
    verify(m).m2(); 
} 

一个想法是在年底来验证嘲笑,但让我们说有一个小愚蠢的执行失误导致调用方法M1两次和M2一次,但不是我所期望的它在testInvalid但最终测试会通过。我希望我的测试早日失败。我如何实现这一目标?

谢谢。

感谢@Woozy编码器:

没有提到的是,reset也将是一种选择,但既然已经验证,下一个平等的存根调用之间被调用,这使得它很难写“很好“和正确的测试,我想。应该有两种不同的嘲弄风格:

  1. “后置”嘲讽为的Mockito做它
  2. “早”嘲讽这将是一个校验块

像后隐式复位:

earlyReset(m).after(
    new Runnable() { 
     t.someMethodInvokingTwoStubs(); 

     verify(m).someMethod1(); 
     verify(m).someMethod2(); 
    } 
); 
+1

试用一下这个【答案】(http://programmers.stackexchange.com/questions/188299/is-this-an-appropriate-use-of-mockitos-reset-method) – kazbeel

+0

不要测试一种测试方法中的多种方法。一个测试应该有一件东西,它测试,最好是一件可能失败的东西。测试多种方法会使测试更加复杂。将测试分为多个测试方法将解决该问题。 –

+0

@WoozyCoder谢谢,编辑我的文章 – Aitch

回答

0

Mockito的写作是为了避免脆弱性,这样验证可以使最小特定的断言成为可能,以允许实现在没有陈的情况下进化对测试进行测试。 如果您的测试系统无关紧要地多次调用这些方法,那么您不应该让Mockito检查它。

替代方案:

  • 使用atLeastatLeastOnce,以保证通话的发生的一切,而不必担心很多额外倍的方法是如何被调用。
  • 如果调用存根返回值,则推断系统根据状态声明来处理已存根据的数据。
  • 如果你真的需要存根或验证行为来改变单个测试方法,那么你的模拟可能会超出Mockito的良好表现。使用单个方法的答案,或编写一个手动伪装,以正确模拟相互关联的方法。
+0

我想过用我的状态机实现一台售票机。它开始于一个IdleState,它应该调用'onIdle',然后我们选择一张票,支付它,它应该返回到IdleState并再次调用'onIdle'。这是一个安静的复杂测试,但它是状态机实现的基础,以及功能文档。在开始时,我期待onIdle被调用,最终在支付票款后。 “at least(2)'最后对我来说太模糊了。我认为Mockito不适合这种集成测试,但我非常喜欢Mockito,因为它很容易使用 – Aitch