利用stub技术进行单元测试
2024-09-01 01:43:14
待测试类:WebClient:
import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class WebClient { /* 测试时的几个要点: 1.这个方法有两个出口: a.正常情况下,返回从服务器发回来的数据 b.如果getInputStream出错,返回一个null c.如果read出错,则返回一个null */ public String getContent (URL url){ StringBuffer content = new StringBuffer(); try{ HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setDoInput(true); InputStream in = connection.getInputStream(); ]; int count; != (count = in.read(buffer))) { content.append(,count)); } } catch (IOException e) { return null; } return content.toString(); } }
使用stub替换web资源的测试方法:
import org.junit.*; import org.mortbay.jetty.Server; import org.mortbay.jetty.handler.AbstractHandler; import org.mortbay.jetty.servlet.Context; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; /* 这种测试的核心思想就是,在我的测试过程中,搭建一个服务器,并在服务器上备上资源, ,我测试的方法,将会来访问我这个服务器,由于服务器中的资源是我自己准备的,所以 我可以对获取的资源的正确性进行判断。 这个测试用到的比价有技术含量的点有: 1.内嵌式服务器Jetty,这个我只需要研究一下Jetty配置自己的处理器 在正式开始整理之前,先回忆一下Tomcat中server.xml标签中说的一些关系: host中有许多个context engine中有许多个host service中有多个connector与一个Engine server中有多个service 我注意到一件事情,在使用Jetty时,作者总是先New出一个Server来,在Server中 设置端口号8080.这个已经和Tomcat有点不一样了。 其次Tomcat中是在web.xml中配置servlet与url的匹配,但是Jetty中是先New出一个 Context,然后将server及相应的url传入。最后调用setHandler()方法,设置该url 的处理类。 Tomcat中Context中的概念貌似和Jetty中的Context是类似的。我没有细究,但是我记得 在写Servlet时,我们总是用到一些Context中的参数。这部分以后再复习一下吧。 感觉把这些东西分析完了,自己也就理解了Jetty配置的过程。 */ @Ignore public class TestWebClient { @BeforeClass public static void setUp() throws Exception { Server server = new Server(8080); TestWebClient t = new TestWebClient(); Context contextOkContext = new Context(server,"/textGetContentOk"); contextOkContext.setHandler(t.new TestGetContentOkHandler()); Context contextNotFoundContext = new Context(server, "/testGetContentNotFound"); contextNotFoundContext.setHandler(t.new TestGetContentNotFoundHandler()); server.setStopAtShutdown(true); server.start(); } private WebClient client; @Before public void ready(){ client = new WebClient(); } @Test public void testGetContentOk() throws Exception{ String result = client.getContent(new URL( "http://localhost:8080/textGetContentOk" )); assertEquals("It works",result); } @Test public void testGetContentNotFound() throws MalformedURLException { String result = client.getContent(new URL( "http://localhost:8080/testGetContentNotFound" )); assertNull(result); } @AfterClass public static void tearDown(){ } public class TestGetContentOkHandler extends AbstractHandler { public void handle(String s, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, int i) throws IOException, ServletException { OutputStream out = httpServletResponse.getOutputStream(); /* 这个地方的写法和我以前看到的不一样哦 */ // ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(); // writer.write("It works"); // writer.flush(); /* 感觉有必要把HTTP学习一下了 */ // httpServletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH,writer.size()); // writer.writeTo(out); // out.flush(); /* 我擦嘞,什么鬼,作者花式秀,结果还是错的,我这简简单单的一写,既然是对的 */ out.write("It works".getBytes("iso-8859-1")); out.flush(); } } public class TestGetContentNotFoundHandler extends AbstractHandler{ public void handle(String s, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, int i) throws IOException, ServletException { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); } } }
利用替换连接的方法:
import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.*; import static org.junit.Assert.assertEquals; /* 第二个方案:替换连接 该方案的核心技术是,利用Java中URL和HttpURLConnection类,我们引入 自定义的协议处理器来处理任何类型的通信协议。 技术要点: 1.为了实现一个自定义的URL协议处理器,你需要调用URL的setURLStreamHandlerFactory 方法,并传递给它一个自定义的URLStreamHandlerFactory。无论何时调用URL的 openConnection方法,都会调用URLStreamHandlerFactory类,返回一个 URLStreamHandler对象。(之前在getContent中调用这个方法时,得到的是一个connection 对象,现在说是一个URLStreamHandler对象,有点奇怪的哦。) public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) 设置应用程序的 URLStreamHandlerFactory。在一个给定的 Java 虚拟机中,此方法最多只能调用一次。 URLStreamHandlerFactory 实例用于从协议名称构造流协议处理程序。 public URLStreamHandler createURLStreamHandler(String protocol) 创建具有指定协议的新 URLStreamHandler 实例。 */ public class TestWebClient1 { @BeforeClass public static void setUP(){ TestWebClient1 t = new TestWebClient1(); URL.setURLStreamHandlerFactory(t.new StubStreamHandlerFactory()); } @Test public void testGetContentOk() throws MalformedURLException { WebClient client = new WebClient(); String result = client.getContent(new URL("http://loalhost")); assertEquals("It works",result); } private class StubHttpURLConnection extends HttpURLConnection { private boolean isInput = true; public StubHttpURLConnection(URL u) { super(u); } /* 你想要的流里,我已经给你放好的东西。 */ @Override public InputStream getInputStream() throws IOException { if(!isInput){ new ProtocolException("Wrong in isInput..."); } ByteArrayInputStream bais = new ByteArrayInputStream( "It works".getBytes("ISO-8859-1") ); return bais; } public void disconnect() { } public boolean usingProxy() { return false; } public void connect() throws IOException { } } private class StubStreamHandlerFactory implements URLStreamHandlerFactory{ public URLStreamHandler createURLStreamHandler(String protocol) { return new StubHttpURLStreamHandler(); } } private class StubHttpURLStreamHandler extends URLStreamHandler{ protected URLConnection openConnection(URL u) throws IOException { return new StubHttpURLConnection(u); } } }
《Junit实战》笔记
最新文章
- Unity中Instantiate一个prefab时需要注意的问题
- XMLHttpRequest 对象
- 使ViewStub 来提高UI的加载的性能
- iOS利用单例实现不同界面间的数据传输
- A Tour of Go Function closures
- 22个CSS黑魔法
- JS验证身份证的合法性
- 《JavaScript高级程序设计》读书笔记 ---变量、作用域和内存问题小结
- R语言︱数据规范化、归一化
- Nginx 常见问题
- Spring事物管理--相关要点及配置事物管理器
- 深入浅出 JVM GC(1)
- 说说CDN
- 自己的memcache类
- 解析img图片没找到onerror事件
- IDFA
- UI5-文档-4.17-Fragment Callbacks
- js 取元素相对页面的高度和宽度
- Generator 函数的异步应用
- Windows上编译Boost
热门文章
- Python写的嗅探器——Pyside,Scapy
- DataVeryLite和Nhibernate性能对比
- .NET架构师知识普及
- 从电子游戏到DevOps
- Laravel --- Laravel5.3 和 Workerman结合使用(异步)
- OVS实现VXLAN隔离
- Storm 学习之路(一)—— Storm和流处理简介
- 安装Flume——海量日志收集聚合系统
- 使用elasticsearch启动项目报错failed to load elasticsearch nodes 。。。。。No type specified for field [name]
- Gradle +HanLP +SpringBoot 构建关键词提取,摘要提取 。入门篇