Java 单元测试发出URL调用的servlet

Java 单元测试发出URL调用的servlet,java,servlets,junit,mocking,Java,Servlets,Junit,Mocking,我想为通过java.net.URL调用web服务的servlet类编写一个单元测试 我可以创建mockrequest和response对象,以便轻松地发送到servlet的doGet方法(使用junit上实用程序员文本中的技术),即创建MockHttpServletRequest、MockHttpServletResponse,并将它们传递给doGet 我遇到的问题是servlet中打开的URL 现在,我只是在调用打开URL并返回字符串的函数(生产代码)和调用直接返回固定URL字符串的函数(测试

我想为通过java.net.URL调用web服务的servlet类编写一个单元测试

我可以创建mockrequest和response对象,以便轻松地发送到servlet的doGet方法(使用junit上实用程序员文本中的技术),即创建MockHttpServletRequest、MockHttpServletResponse,并将它们传递给doGet

我遇到的问题是servlet中打开的URL

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

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

我可以想出很多方法来实现这一点,但没有一种方法是正确的

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

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

  • 示例3:创建一个带有静态字段的类,指示是否要使用mock,并根据字段值在servlet中设置URL访问条件。负面:感觉像是全局变量

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

经过一上午的搜索,我找不到完全正确的答案,因此我求助于苏的集体智慧

谢谢, 阿德南

ps-我应该提到,我不必使用java.net.URL,任何等效的东西都可以使用。

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

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


这类事情是IoC/DI的一个典型例子。

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


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

感谢tomasz和dave-我在搜索过程中看到了对IoC的引用,但无法完全建立连接。我将返回并再次检查-欢迎链接到您可能知道的任何高质量教程。@user453026我可能会尝试搜索“控制反转”或“依赖注入”加上“教程”。。。不过,它们中的大多数在搜索时都是特定于框架的。不过,即使不了解底层框架,它们中的大多数都将有助于将基础可视化。