繁体   English   中英

如何在没有(非默认)构造函数的Java类中模拟对象?

[英]How do I mock objects in a Java class that has no (non-default) constructor?

我正在为遗留的Tomcat Web服务设置第一个单元测试,这个测试没有考虑到测试,并且不使用Spring。 我遇到问题的一个类是一个扩展HttpServlet的servlet。 这是该类的缩写版本。

public class ItemServlet extends HttpServlet {
    private ObjectMapper mapper;
    private IItemDAO dao;

    @Override
    public void init() {
        mapper = new ObjectMapper();
        dao = new GenericItemDao(...);
    }
}

通常我会将外部依赖项传递给构造函数,但是servlet是由Tomcat基于web.xml配置创建的,它只调用默认构造函数和无参数init()方法。 结果,在单元测试中似乎没有任何方法可以进行依赖注入以允许我的模拟。 我能想到这样做的唯一方法是创建一个仅测试构造函数,我可以使用它来从我的单元测试中实例化类,并使init()方法保持实际应用程序调用的方式。 我还可以创建第三个方法,可以由构造函数和init()调用,如下所示:

public class ItemServlet extends HttpServlet {
    private ObjectMapper mapper;
    private IItemDAO dao;

    public ItemServlet(ObjectMapper mapper, IItemDAO dao) {
        initDependencies(mapper, dao);
    }

    private void initDependencies(ObjectMapper mapper, IItemDAO dao) {
        this.mapper = mapper;
        this.dao = dao;
    }

    @Override
    public void init() {
        initDependencies(new ObjectMapper(), new GenericItemDAO(...));
    }
}

是否有更简洁的方法来对这些类进行单元测试?

我会利用这个机会来解耦代码并使其可测试。 实际上,如果你代表Tomcat实例化一个servlet,只是为了检查它的一个方法是否返回了一个期望的值,你就会超出单元测试领域,而是进行集成测试。

使用Mock框架解决这个问题会使当前的实现失败并使其无法改变 - 除非这些更改伴随着测试的变化。

我是单元测试的绝对支持者,而且我也是一个实用主义者,如果我发现自己处于难以测试的几个框架层中,我就会尽可能做到这一点。 在这种情况下(我只知道你的servlet依赖,而不是任何其他 - 你会知道你在哪里)我喜欢将我的代码分成

  • 原子的,可单元测试的单元,没有框架依赖性
  • 连接代码,将可测试代码与框架连接起来。

接线代码自然不是很复杂,并且没有得到任何测试(由于大量的依赖性)。 虽然它得到同行评审。

你可以在类中添加getters / setters ,然后通过那里将mocks注入到类中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM