2011-10-21 39 views
3

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

我可以创建模拟请求和响应对象发送到servlet的doGet方法容易地(使用的技术从上junit的语用程序员文本),即,创造MockHttpServletRequest,MockHttpServletResponse,并通过这些来的doGet。

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

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

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

我可以想到一些实现这一点的方法,但没有一个感觉正确。

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

  • 例2:有两个类实现网络访问,其中之一是模拟;让junit重新加载模拟类,生产代码加载常规类(或以某种方式将生产类重新映射到模拟类)。消极:不确定如何做到这一点;看起来笨拙。示例3:有一个静态字段类,用于指示我是否想要使用mock,并根据字段值调整servlet中的URL访问权限。负面:感觉像全局变量。

  • 例4:扩展URL,这样如果我切换到URL(但java.net.URL是final),生产代码将正常工作。

通过搜索的早晨我找不到正确的答案,因此我转向了集体智慧。

感谢, 阿德南

PS - 我要指出,我没有使用的java.net.URL,任何这相当于将工作。

回答

3

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

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

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

+0

感谢tomasz和戴夫 - 我在我的搜索过程中看到对IoC的引用,但无法完成连接。我会回去再检查一遍 - 欢迎您链接到任何您可能知道的高质量教程。 – adnan

+0

@ user453026我可能只是试着寻找“控制反转”或“依赖注入”加上“教程”......尽管如此,它们大多数都是特定于框架的。尽管他们中的大多数人都会理解基础框架,但他们大多会帮助您理解基础知识。 –

2

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

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