我想为一种方法使用两个自定义匹配器。 基本上,如果我传递方法VALUE_A,我希望它返回RESULT_A,如果我VALUE_B传递它,我希望它返回RESULT_B。 所以这里有一个代码摘录:
class IsNonEmpty extends ArgumentMatcher<Get> {
public boolean matches(Object get) {
//For some reason, this method is called when I assign the IsEmpty matcher to MockHtable.get()
//When this happens, the value of the get argument is null, so this method throws an NPE
return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key));
}
}
class IsEmpty extends ArgumentMatcher<Get> {
public boolean matches(Object get) {
return !(Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)));
}
}
[...]
//This line executes just fine
Mockito.when(mockHTable.get(Mockito.argThat(new IsNonEmpty()))).thenReturn(dbResult);
[...]
//This line calls IsNonEmpty.matches() for some reason. IsNonEmpty.matches() throws an NPE
Mockito.when(mockHTable.get(Mockito.argThat(new IsEmpty()))).thenReturn(emptyResult);
当我将 IsEmpty 自定义匹配器分配给 mockHTable.get() 方法时,它会调用 IsNonEmpty.matches() 函数。 不知道它为什么要这样做。 所以我将 IsNonEmpty 类更改为:
class IsNonEmpty extends ArgumentMatcher<Get> {
public boolean matches(Object get) {
//For some reason, this method is called when I assign the IsEmpty matcher. Weird, no?
if(get == null) {
return false;
}
return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key));
}
}
然后一切正常! 当我将 IsEmpty 匹配器分配给 mockHTable.get() 函数时,仍然会调用 IsNonEmpty.matches(),但我的匹配器完全按照它们应该的方式工作。
那么这是怎么回事呢? 为什么会这样? 我的解决方法是补偿这种古怪行为的适当方法,还是我做错了?
IsNonEmpty.matches()
在存根的第二行被调用的原因是Mockito.argThat(new IsEmpty())
返回 null,然后将其传递给 mockHTable.get()
。 必须根据前面的存根检查此调用,以查看它是否匹配;这意味着打电话给IsNonEmpty.matches()
.
我不确定为什么这会让你的测试失败 - 如果不看到所有代码,很难分辨。
但是,我强烈建议在您必须多次存根相同的模拟时使用 doReturn...when
而不是 when...thenReturn
。 如果您这样做,您不会遇到这样的问题。 事实上,我更喜欢使用doReturn...when
而不是总是when...thenReturn
(以及类似的doThrow
和doAnswer
),尽管大多数人更喜欢when...thenReturn
。
使用 doReturn...when
语法重写其中一个存根行如下所示。 另一个是类似的。
Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty()));
最后,代表Mockito开发团队(我是其中的一员)提出请求。如果您认为这里的 Mockito 中存在错误 - 从您的描述来看,我认为很可能有 - 请
- 向 Mockito 邮件组发送消息 (mockito@googlegroups.com) 或
- 在 Mockito 问题列表 (http://code.google.com/p/mockito/issues/list) 上提出问题。
如果你能真正发布一个完整的示例,而不仅仅是你认为的关键行,这对Mockito团队很有用 - 有时Mockito问题的原因在一个非常意想不到的地方。