在Mock对象上调用方法是调用实际方法而不是模拟实现

use*_*481 3 java unit-testing mockito

我的代码如下

public process() {
    extract();
    ...
}

private Obj extract() {
    Constructor const = new Constructor();
    Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
    return object;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用mockito测试方法过程.在我的测试课中,我编写了代码

Constructor mocckConst = mock(Constructor.class);
Obj mockObject = mock(Obj.class);
when(mocckConst .getOBJMethod("12345","c:/file/a.zip",null).thenReturn(mockObject);
Run Code Online (Sandbox Code Playgroud)

但是当调用extract方法执行testcase时,它将转向getOBJMethod()的实际实现.

构造函数类有另一个内部类.这会导致任何问题吗?任何人都可以告诉我这里出了什么问题和解决方案.

我想即兴创作我的流程方法.

public process(String base) {
    if("abc".equals(base)) {
       ---
    }
    else if("def".equals(base) {
    extract();
    ---
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,只有在def为def时才会调用extract().而且我不想将构造函数对象传递给process()方法然后是否有任何解决方案?

小智 5

在您要测试的类中,您创建一个新的Constructor对象(via Constructor const = new Constructor()),因此,您始终使用REAL实现.Constructor如果要将对象替换为模拟对象以进行测试,则必须注入对象.注入也可以通过构造函数进行测试.

private final Constructor const; // remove final, if required

public <ConstructorOfYourClassHere>(Constructor const) {
    assert const != null : "const != null"; // use assertions, if you like

    this.const = const;

    // other constructor code...
}

// your other code here...

public process(String base) {
    if("abc".equals(base)) {
        // ---
    }
    else if("def".equals(base) {
        extract();
        // ---
    }
}

private Obj extract() {
    Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
    return object;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在创建测试对象并调用时注入模拟process().然后将使用您的模拟实现.

BTW:

  • 如果您是代码的所有者,则可能需要更改extract方法的可见性,protected以便您也可以测试该方法.看到这里.
  • 此外,您可能希望阅读有关依赖注入的内容.使用DI进行测试通常要容易得多.您不必使用DI框架,只需通过方法参数注入依赖项,或者在对象创建时通过构造函数注入依赖项.