2012-04-26 46 views
6

我想为单个方法使用两个自定义匹配器。基本上,如果我传递方法VALUE_A,我希望它返回RESULT_A,并且如果我将它传递给VALUE_B,我希望它返回RESULT_B。所以这里有一个代码摘录:当我将多个自定义匹配器分配给单个方法时,Mockito会出现奇怪的现象

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()仍然被调用,但是我的匹配器完全按照他们的方式工作。

那么有什么交易?为什么会发生?我的工作是否是补偿这种古怪行为的适当方法,还是我做错了?

回答

11

IsNonEmpty.matches()在第二行存根上被调用的原因是Mockito.argThat(new IsEmpty())返回null,然后传递给mockHTable.get()。这个电话必须与早期的存根进行核对,看看它是否匹配;这意味着拨打IsNonEmpty.matches()

我不确定为什么这会让你的测试失败 - 很难说没有看到所有的代码。

但是,我会认真地推荐使用doReturn...when而不是when...thenReturn,只要你不得不多次存根同一个模拟。如果你这样做,你不会遇到这样的问题。实际上,我总是倾向于使用doReturn...when而不是when...thenReturn(并且类似doThrowdoAnswer),尽管大多数人更喜欢when...thenReturn

使用doReturn...when语法重新编写您的存根线之一如下所示。另一个是相似的。

Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty())); 

最后,我代表Mockito开发团队(我是其中一员)提出请求。如果你认为这是在一个的Mockito错误在这里 - 从你的描述,我觉得有可能是 - 请透过

  • 将消息发送到邮件的Mockito组([email protected])OR
  • 在Mockito问题列表中提出问题(http://code.google.com/p/mockito/issues/list)。

如果你真的可以发布一个完整的例子,而不仅仅是你认为的关键线 - 有时Mockito问题的原因是在一个非常意想不到的地方,这对Mockito团队很有用。

相关问题