簡體   English   中英

具體類Mockito中的模擬鏈接的呼叫

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM