我刚接触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个异常/错误。另外,我在'matches'函数的开头放了一个断点,它永远不会被击中。
3个问题: 1)为什么我的论证匹配者不抱怨一个不好的论点? 2)检测到不良参数后的预期输出是多少? 3)代码如何检测错误的参数?
答案 0 :(得分:1)
我不知道为什么你的断点没有触发,但我在匹配器中抛出一个System.out.println("Hello")
断点,它被击中就好了。事实证明,“asdf”和“Asdf”都在您的测试中匹配,因为匹配器中的条件具有||
而不是&&
。在我更正后,又切换到>=
和<=
而不是>
和<
:
return (str.charAt(0) >= 'A' && str.charAt(0) <= 'Z' );
...然后我按预期分别获得true
和false
。
请注意,模拟List
和Deque
之类的接口比使用LinkedList
这样的具体类更安全,因为具体类可以使用Mockito无法模拟的最终方法。 (在现实世界的非示例测试中,您应该使用真实的LinkedList
和test state instead of interaction。)
因为您在when
语句中使用了匹配器,所以您正在设置匹配器匹配时的预期行为。如果不匹配,如果您没有设置任何其他期望,Mockito会返回其default boolean return value,false
。
Unlike EasyMock's record-replay pattern,在测试过程中主动捕获错误的互动,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)
来解决此问题,但通常这些默认值(如false
和null
)会破坏您的测试断言或系统测试。