2014-05-22 43 views
0

我有这样的代码:接口的Mockito方法冲突

import static org.mockito.Matchers.any; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.verify; 

import org.junit.Test; 

interface IListener<E> { 
    void onEvent(E e); 
} 

interface MyListener extends IListener<String> { 
    @Override 
    void onEvent(String s); 
} 

public class XYZ { 
    @Test 
    public void test() { 
     MyListener myListener = mock(MyListener.class); 
     IListener<String> listener = myListener; 
     listener.onEvent("XYZ"); 
     verify(myListener).onEvent(any(String.class)); 
    } 

} 

这导致检测失败。据我所知,在MyListener中重写onEvent方法是过度的,但它允许Java,并可以由第三方编码器完成。

你能解释一下,为什么会导致测试失败,而如果MyListener不重写onEvent方法,一切正常。

+0

故障信息状态到底是什么?乍一看,这似乎应该通过。 –

+0

如果您使用'myListener.onEvent(“XYZ”)'而不是?或者'verify(listener).onEvent(any(String.class));'? –

+0

@Jon_Skeet然后它工作得很好! –

回答

2

既然你做的事:

IListener<String> listener = myListener; 
listener.onEvent("XYZ"); 

这意味着IListener.onEvent()被调用。但Mockito的代理超过MyListener,并且您在后者中重新定义了.onEvent()

因此,Mockito不会看到您拨打IListener的电话.onEvent()

如果您删除覆盖.onEvent()MyListener然后它会工作(为什么你首先覆盖它的方式?)。要做到这一点


一种方法是启动您的模拟为IListener<String>,而不是MyListener

另一种方式,但urgh。请注意,你的模拟必须是最终的才能工作。

doAnswer(new Answer<Void>() 
    { 
     @Override 
     public Void answer(final InvocationOnMock invocation) 
      throws Throwable 
     { 
      final String o = (String) invocation.getArguments()[0]; 
      myListener.onEvent(o); 
      return null; 
     } 
    }).when((IListener<String>) myListener).onEvent(anyString()); 
+0

我没有。这是我使用的第三方代码,它被编码为怪异的方式。但问题是,如果可以用Java来完成,应该有一种方法来测试它。 –

+0

好吧,看到答案,但你的情况很奇怪 – fge

+0

实际上还有另外一种方法,看答案 – fge