如何在单元测试中模拟 ServletContext 以访问 WAR 资源?

Posted

技术标签:

【中文标题】如何在单元测试中模拟 ServletContext 以访问 WAR 资源?【英文标题】:How to mock ServletContext to access WAR resources in unit test? 【发布时间】:2021-10-29 06:52:05 【问题描述】:

我有一个 Jetty 网络应用程序,它正在通过 Maven 打包并部署为 .war。我使用 Apache Freemarker 作为应用程序的一部分来处理和创建文档。这意味着我需要能够加载打包在 WAR 中的模板文件。 Freemarker 提供了一种方法来执行此操作(Configuration.setServletContextForTemplateLoading),但它需要传入ServletContext 的实例作为参数。在生产代码中很容易,但是在单元测试方面我有点卡住了。我那里没有 ServletContext,那么如何让实例传递给 Freemarker?有没有办法通过模拟来做到这一点?我尝试使用 Spring 中的MockServletContext,但无法正常工作。我什至不确定是否可以在没有 Spring 框架的其余部分的情况下使用该库。

任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

出于测试目的,最好使用MockServletContext,因为这样您的测试更接近生产系统。如果由于某种原因这太成问题,还有另一种方法,假设是您的代码调用了setServletContextForTemplateLoadingconfiguration.setServletContextForTemplateLoading(servletContext) 只是configuration.setTemplateLoader(new WebappTemplateLoader(servletContext)) 的一种方便方法。因此,在您的代码调用setServletContextForTemplateLoading 的地方,您可以改为调用setTemplateLoader,然后将TemplateLoader 公开为一个bean,它在生产中是WebappTemplateLoader,但在测试期间被ClassTemplateLoader 实例替换。 (实际上,也许你可以在生产和测试中使用ClassTemplateLoader。)

【讨论】:

你知道 MockServletContext 的好例子或教程吗?它似乎确实提供了我想要的东西,但我发现的每一点信息似乎都假设使用了完整的 Spring 框架。我只想模拟我的上下文;我不需要所有其他行李。 @pbuchheit 我不知道任何细节,但它是 Spring Test 的一部分,因此,您需要 Spring 作为它的依赖项。我假设你的项目无论如何都使用 Spring,但如果不是......也许其他模拟/假人存在。

以上是关于如何在单元测试中模拟 ServletContext 以访问 WAR 资源?的主要内容,如果未能解决你的问题,请参考以下文章

如何在服务层单元测试中模拟数据库结果?

如何在单元测试中模拟缺乏网络连接

如何在 JavaScript 单元测试中模拟 localStorage?

单元测试:如何在反应中模拟 axios?

如何在单元测试中模拟 AngularFire 2 服务?

如何在 Grails 单元测试中使用 Spock 模拟 passwordEncoder