mockito 模拟孔隙法

62o28rlo  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(152)

如何为下面的方法编写mockito测试?IntReqDecorate.decorate为调用添加一个Id。

public class IntVisitor implements Visitor {

    private final IntReqDecorator intReqDecorator;

    public InternalCallVisitor() {
        this.intReqDecorator = new IntReqDecorator();
    }

    @Override
    public void apply(Call call) {
        intReqDecorator.decorate(call);
    }
}
yqkkidmi

yqkkidmi1#

这里有一点束缚,IntVisitor类与具体类IntReqDecorator紧密耦合,并且apply方法被定义为执行与intReqDecorator.decorate相同的操作,因此,在不更改任何签名的情况下,最好的方法是重新编写与decorate相同的测试。
现在,你应该做的就是打破这个依赖关系。首先,你的构造函数在构造IntReqDecorator的时候就具体地构建它。你仍然可以把它作为一个方便的默认值来做,但是你应该为调用者提供一种方法来指定他们想要使用的装饰器。我们可以通过重载构造函数来做到这一点。

public InternalCallVisitor() {
  this(new IntReqDecorator());
}

public InternalCallVisitor(IntReqDecorator intReqDecorator) {
  this.intReqDecorator = intReqDecorator;
}

现在,单凭这一点就足以让我们编写出一个好的测试,我们可以模拟IntReqDecorator并在测试中使用单参数构造函数。
但是我会更进一步。你只使用过IntReqDecorator中的一个方法,即decorate。但是因为它是一个具体的类,它可能有我们在这里并不真正需要的其他方法。所以为了遵循dependency inversion,创建一个接口IntReqDecoratorLike可能是一个好主意(为您的用例选择一个更好的名称),它只有一个方法,然后让IntReqDecorator * 实现 * 该接口。
然后你的构造函数接受一个IntReqDecoratorLike,它 * 只能 * 做我们需要它做的事情。这样做的好处是你几乎不需要模拟任何东西来测试它。理论上你可以写一个新的实现IntReqDecoratorLike并在测试中使用的类。我们可能仍然会使用模拟框架,因为它确实提供了很好的错误消息和内置验证,但原则上存在替代方法。
作为一个非常广泛的一般规则,当你发现自己挠头说“这段代码看起来很难测试”时,你应该退一步。因为通常情况下,你可以对API进行修改,不仅使测试更容易,而且使代码更符合人体工程学。

相关问题