如何在运行junit测试用例时避免实际的方法调用

时间:2013-11-12 04:17:31

标签: java junit mocking

我有以下情况。

我在其中MyClass的班级myAPI(),其内容如下:

class MyClass {
    public void myAPI() {
        ...
        MyOtherClass myOtherObj = new MyOtherClass();
        String value = myOtherObj.decodeAndGetName();
        ...
    }
}

此处我们MyOtherClass包含执行某些操作的API decodeAndGetName()。它位于不同的包中,我无法修改其代码。

要求

我需要为上面的myAPI()编写一个junit测试。现在我想以某种方式模拟MyOtherClass的对象并模拟decodeAndGetName()的返回值。

我无法执行此操作,因为我们有new MyOtherClass(),当流程到达此行时,它会创建一个新实例并转到decodeAndGetName() API。 我需要的是,在上面的代码中遇到此调用时,某种方法可以阻止流转到decodeAndGetName()并采用模拟值。

请让我知道一种方法。

1 个答案:

答案 0 :(得分:1)

我只使用Android代码,但我认为您可以使用Mockito之类的东西来模拟测试中的MyOtherClass,其代码类似于:

MyOtherClass mockMyOtherClass = Mockito.mock(MyOtherClass.class);
when(mockMyOtherClass.decodeAndGetName()).thenReturn(new String("known return value");

我还建议使用依赖注入并使用Guice之类的东西来实现这一点。我使用Guice&组合Mockito每天与我的Android项目一起成功地完成了这类事情。

简要示例
在使用Guice设置依赖注入之后,以下是您的代码的样子:

MyOtherClassWrapper.java

@Singleton
public class MyOtherClassWrapper {

    private MyOtherClass myOtherClass = new MyOtherClass();

    public String decodeAndGetName() {
        return getMyOtherClass().decodeAndGetName();
    }

    ...

    private MyOtherClass getMyOtherClass() {
        return myOtherClass;
    }

}

MyClass.java

class MyClass {

    ...

    @Inject private MyOtherClassWrapper myOtherClassWrapper;

    ...

    public void myAPI() {
    ...
    String value = getMyOtherClassWrapper().decodeAndGetName();
    ...
    }

    private MyOtherClass getMyOtherClassWrapper() {
        return myOtherClassWrapper;
    }
}

有关如何开始设置Guice的信息,请参阅Guice User's Guide。这不是太难。