在具体类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(...)调用,因此不会引发异常,从而导致断言失败。

请帮忙。谢谢。

何塞·马丁内斯(Jose Martinez)

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);包装在另一个方法中。

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);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章