我有以下情况。

我有一个API 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()并在上面的代码中遇到此调用时采用模拟值的方法。

请让我知道一种方法。

最佳答案

我只将其与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。不太困难。

10-04 10:08