单元测试进行URL调用的servlet

时间:2011-10-21 19:46:57

标签: java servlets junit mocking

我想为servlet类编写单元测试,该类通过java.net.URL调用Web服务。

我可以创建模拟请求和响应对象,以便轻松地发送到servlet的doGet方法(使用junit上的实用程序员文本中的技术),即创建MockHttpServletRequest,MockHttpServletResponse,并将这些传递给doGet。

我遇到问题的部分是在servlet中打开的URL。

现在,我只是在调用打开URL的函数并返回一个字符串(生产代码)和调用返回的函数之间进行选择,该函数直接返回一个固定URL的字符串(测试代码)

理想情况下,我想要一个doGet方法,其中测试代码是不可见的 - 在进行网络访问的函数和直接返回字符串的函数之间的选择应该对doGet是透明的。

我可以想到实现这一目标的多种方法,但没有一种感觉正确。

  • 示例1:将函数包装在具有testOn布尔值和setTestMode方法的类中; junit init可以将testMode设置为true,默认为false。 testOn决定调用哪个方法。否定的是,我需要一个新的课程,似乎可能会失控。

  • 示例2:有两个实现网络访问的类,其中一个是mock;让junit重新加载mock类,生成代码加载常规类(或以某种方式将生产类重新映射到mock类)。否定:不确定如何做到这一点;看起来很笨拙。

  • 示例3:有一个带有静态字段的类,指示我是否要使用模拟,并根据字段值调整servlet中的URL访问。否定:感觉就像全局变量。

  • 示例4:扩展URL,如果我只切换到URL(但java.net.URL是最终的),生产代码将正常工作。

通过上午的搜索,我找不到合适的答案,因此我转向了SO的集体智慧。

谢谢, 阿德南

ps - 我应该提一下,我不必使用java.net.URL,任何相同的东西都可以工作。

2 个答案:

答案 0 :(得分:3)

您的第二个选项是“正确”选项。对外部URL的调用应该封装在服务中。然后,该服务被注入使用它的servlet中。这是Inversion of Control派上用场的地方。

在您的单元测试中,您将注入测试实现,在现实生活中,您将注入一个真正的实现。它可以像为服务提供setter一样简单,并将实现默认为“真正的”。

这种事情是IoC / DI的典型例子。

答案 1 :(得分:2)

看起来你正在重新发明轮子 - 你又在示例2 中发明了它。这通常使用依赖注入来实现,实际上是迄今为止软件开发人员提出的最佳解决方案。

隐藏界面后面的Web服务调用。一个实现执行实际调用,而另一个实现是可以配置的模拟。如果您没有使用任何DI框架(Spring,Guice,EJB / CDI),请在测试中手动替换生产实现。

相关问题