我正在为遗留的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依赖,而不是任何其他 – 你会知道你在哪里)我喜欢将我的代码分成
>原子,可单元测试的单元,没有框架依赖性
>接线代码,用于连接可测试代码和框架.
接线代码自然不是很复杂,并且没有得到任何测试(由于大量的依赖性).虽然它得到同行评审.
标签:java,unit-testing,mocking,tomcat
来源: https://codeday.me/bug/20190829/1760821.html