1

我是 Android 测试新手,并决定从http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#3中的 Mockito 示例开始

为了完全理解发生了什么,我决定从示例中分支出来,这是我的代码:

@Test
public void testMatchers() throws Exception
{
  LinkedList <String> mockedList = mock (LinkedList.class);
  when (mockedList.contains(argThat(isValidStr()))).thenReturn(true);
  System.out.println(mockedList.contains("Asdf")); // prints 'true', as expected
  System.out.println(mockedList.contains("asdf")); // prints 'true' which I guess makes sense... but shouldn't the argument matcher complain somehow?

}
public static ArgumentMatcher<String> isValidStr()
{
  return new ArgumentMatcher<String> ()
  {
    @Override
    public boolean matches ( Object argument ) 
    {
      String str = (String) argument;
      return (str.charAt(0) > 'A' || str.charAt(0) < 'Z' ) // if first letter is capitalized
    }
  }
}

所有测试都通过了,有 0 个异常/错误。另外,我在“匹配”函数的开头放置了一个断点,它永远不会被命中。

3 个问题:1)为什么我的论点匹配器不抱怨一个糟糕的论点?
2) 检测到错误参数后的预期输出是什么?3) 检测到错误参数的代码看起来如何?

4

1 回答 1

1
  1. 我不知道为什么你的断点没有触发,但是我System.out.println("Hello")在匹配器中扔了一个断点,它被击中就好了。事实证明,“asdf”和“Asdf”在您的测试中都匹配,因为您在匹配器中的条件是 a||而不是 a &&。一旦我纠正了这一点,并切换到>=and<=而不是>and <

    return (str.charAt(0) >= 'A' && str.charAt(0) <= 'Z' );
    

    ...然后我得到truefalse,正如预期的那样。

    请注意,模拟 和 之类的接口比模拟 之ListDeque的具体类更安全LinkedList,因为具体类可以具有 Mockito 默默无法模拟的最终方法。(在现实世界的非示例测试中,您可能应该使用真实LinkedList测试状态而不是交互。)

  2. 因为您在when语句中使用匹配器,所以您正在设置匹配器匹配时的预期行为。当它不匹配时,如果您没有设置任何其他期望,Mockito 将返回其默认的布尔返回值, false

  3. 与 EasyMock 的记录重放模式不同,它会在测试期间主动捕获不良交互,Mockito 有一个存根测试验证模式,它仅在您手动要求时“检查”不良交互:

    // Verify that contains is never called with an invalid string.
    verify(mockedList, never()).contains(argThat(not(isValidStr()));
    

    按照惯例,这将在您的测试结束时进行。另一个明显的验证如下所示:

    verify(mockedList).contains(argThat(isValidStr()));
    

    ...但这实际上会通过,因为它会将您的第一个呼叫与“Asdf”匹配,而忽略您与“asdf”的第二个呼叫。您可以通过添加verifyNoMoreInteractions(mockedList)到上面的验证来解决这个问题,但通常这些默认值会破坏您falsenull测试断言或被测系统。

于 2013-10-20T01:08:24.407 回答