这两天在研究jetty和junit联合进行stub方式测试的东西,小有所得,参考的书籍是《junit in action》,不过此书出的比较早,用的jetty版本也比较低,对于现在最新版的6.1.26,变化太大,书中的例子已不好用,花了很多功夫转换成最新的版本。
Jetty是一个轻量级的web容器,其明显的优点就是可以嵌入到java程序中,从程序中启动,定制handler去处理请求,这个特点可以用在单元测试中,可以以stub的方式进行模拟的测试,不必启动真实的服务器。 首先给出一个简单的示例,说明如何嵌入及响应请求。
index.html里只有一句:hello,theoffspring
启动这段程序后,在浏览器中输入http://127.0.0.1:8080/,即可看到index.html里面的内容,是不是很简单?
再贴一段程序来发起一个http请求,基于刚才的例子。
这是以程序的方式去请求一个地址,结果和你在浏览器中输入网址一个效果,试了一下,访问真实的url的时候,比如网易首页,会被重定向,返回的status为302,穿墙能力显然不够强,不过这也用不着。此处contentExchange.waitForDone()表明请求的方式是同步的,另有一种异步的方式:
它需要你去实现一个ContentExchange,定义响应返回时如何进行处理,要异步,这是必然的,很好理解。
行了,基础知识讲完了,下面演示如何结合junit写一个单元测试,目的是先定义一个请求处理器,对于某个特定的url,进行某种内容的响应返回,然后单元测试一下,是不是和期望的结果一致。
因为启动和停止服务器需要一定的时间,这两个操作写到每个TestCase中的setup和teardown里显然不是一种明智的办法,因为太耗时间,所以咱们让它继承一个TestSetup类,这样,一组测试只执行一遍启动和停止的操作。
源代码:
测试用例:
注意,WebClient是哪里来的,自定义的,用来处理发出请求的逻辑,一个方便类而已。
全部代码就是这些,这个例子当然很简单,但足以说明stub方式的运行机制,有时候,为了测试你的业务方法,启动一个真实的服务器如weblogic很费时间,或者你的程序依赖别人的模块,而别人的模块还没有写好,这时stub方式就派上用场了,你embed一个jetty进去,定义一个handler,返回你的业务方法的处理结果,就可以专注于你的功能的测试了。如果你连用jetty也嫌heavy了,那就用自定义的HttpURLConnection去实现吧,呵呵,那个用起来太麻烦,强烈不推荐。