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

时间:2014-08-04 07:09:38

标签: 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;
}

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:5)

在您要测试的类中,您创建一个新的Constructor对象(通过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;
}

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

<强>顺便说一句

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

答案 1 :(得分:1)

如果你想让它可以用mock进行测试,你可以监视Constructor对象。

public class Test{

    @spy
    Constructor const;

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

    private Obj extract() {

        Obj object = const.getOBJMethod("12345","c:/file/a.zip",null);
        return object;
    }
    }