2014-05-22 46 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