[英]Mocking Chained calls in Concrete Class Mockito
我正在使用Mockito服務來測試可能在MyFinalClass中引發並在MyAbstractClass中捕獲的異常,因為具體方法在MyFinalClass中調用了getObject方法。
請參見下面的代碼。
public abstract class MyAbstractClass{
@Autowired
private MyFinalClass myFinalClass;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = myFinalClass.getObject(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
}
public final class MyFinalClass {
public Object getObject(String name) throws MyException{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}
}
public MyException extends Exception{
....
}
以下是我編寫的測試課程。 不幸的是,我遇到了Mockito.when(myFinalClass).getObject(name).thenReturn(Mockito.mock(Object.b))的問題,因為它似乎沒有被調用。
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
@RunWith(PowerMockRunner.class)
public class MyAbstractClassTest {
public static class ExampleConcreteClass extends MyAbstractClass{
}
@InjectMocks
ExampleConcreteClass exampleConcreteClass;
@Mock
MyFinalClass myFinalClass;
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testMyConcreteMethod(){
try{
Mockito.when(myFinalClass).getObject(name).
thenThrow(new MyException());
exampleConcreteClass.myConcreteMethod();
Assert.fail();
}catch(MyException e){
Assert.assertTrue(Boolean.TRUE);
}
}
}
因為MyFinalClass中的getObject(String name)方法的實現尚未完成,所以我在getObject方法的調用上拋出了新的MyException()。 但是,由於未調用Mockito.when(...)調用,因此不會引發異常,從而導致斷言失敗。
請幫忙。 謝謝。
Mockito無法模擬最終課程。 有幾種方法可以解決此問題。
1)在MyAbstractClass
考慮不引用最終類,而應引用MyFinalClass
實現(或擴展)的接口或抽象類。 因此,可以說MyFinalClass
實現了一個名為MyGettableApi
的接口。 然后MyAbstractClass
看起來像這樣。
public abstract class MyAbstractClass{
@Autowired
private MyGettableApi gettableService;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = gettableService.getObject(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
}
public final class MyFinalClass implements MyGettableApi {
@Override
public Object getObject(String name) throws MyException{
**** HAS NOT YET BEEN IMPLEMENTED ****
return null;
}
}
public interface MyGettableApi {
public Object getObject(String name);
}
現在,在您的測試代碼中,您可以模擬MyGettableApi
,因為它不是最終的,沒有問題。
@Mock
MyGettableApi myFinalClass;
2)解決此問題的另一種方法是包裝對myFinalClass.getObject(name);
的調用myFinalClass.getObject(name);
包裹在另一種方法中。
public abstract class MyAbstractClass{
@Autowired
private MyFinalClass myFinalClass;
//concrete method
protected Object myConcreteMethod(String name){
try{
Object b = myGetObjectWrapperMethod(name);
return b;
} catch(MyException e){
LOGGER.log("ERROR THROWN" + e);
}
}
Object myGetObjectWrapperMethod(String name) {
return myFinalClass.getObject(name);
}
}
現在,在您的測試代碼中,您將@Spy
正在測試的MyAbstractClass
實例。
@InjectMocks
@Spy
ExampleConcreteClass exampleConcreteClass;
那么您可以模擬出我們的新包裝方法。
doThrow(new MyException()).when(exampleConcreteClass).myGetObjectWrapperMethod(name);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.