stub是代码的一部分,我们要对某一方法做单元测试时,可能涉及到调用第三方web服务。假如当前该服务不存在或不可用咋办?好办,写一段stub代码替代它。

stub 技术就是把某一部分代码与环境隔离起来(比如,通过替换 Web服务器、文件系统、数据库等手段)从而进行单元测试的。

下面演示一个例子,利用jetty编写相关的stub充当web服务器,返回适当内容。

环境: idea + spring boot + jetty

关于jetty服务器,对比tomcat更轻量级,可轻松嵌入java代码启动它。

如何在项目中启动一个jetty服务器?

package com.lhy.junitkaifa.stubs;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ResourceHandler; /**
* @author xusucheng
* @create 2018-12-20
**/
public class JettySample {
public static void main(String[] args) throws Exception {
Server server = new Server( 8081 ); ContextHandler context = new ContextHandler(server,"/");
//默认为项目根目录
context.setResourceBase(".");
context.setHandler(new ResourceHandler()); server.setStopAtShutdown( true );
server.start();
}
}

请求:http://localhost:8081

编写一个获取url内容的工具方法叫WebClient

package com.lhy.junitkaifa.stubs;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL; /**
* 读取指定URL内容
* @author xusucheng
* @create 2018-12-20
**/
public class WebClient {
public String getContent( URL url )
{
StringBuffer content = new StringBuffer();
try
{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput( true );
InputStream is = connection.getInputStream();
byte[] buffer = new byte[2048];
int count;
while ( -1 != ( count = is.read( buffer ) ) )
{
content.append( new String( buffer, 0, count ) );
}
}
catch ( IOException e )
{
return null;
}
return content.toString();
} public static void main(String[] args) throws Exception{
WebClient wc = new WebClient();
String content = wc.getContent(new URL("http://www.baidu.com/")); System.out.println(content);
}
}

编写测试类TestWebClient

package com.lhy.junitkaifa.stubs;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.http.HttpHeaders; 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.URL; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; /**
* @author xusucheng
* @create 2018-12-20
**/
public class TestWebClient {
private WebClient client = new WebClient();
private static final int PORT=8081; @BeforeClass
public static void setUp() throws Exception{
System.out.println("====================Befor Class====================="); Server server = new Server(PORT);
TestWebClient t = new TestWebClient(); ContextHandler contentOkContext = new ContextHandler(server,"/testGetContentOk");
contentOkContext.setHandler(t.new TestGetContentOkHandler()); ContextHandler contentErrorContext = new ContextHandler(server,"/testGetContentError");
contentErrorContext.setHandler(t.new TestGetContentServerErrorHandler()); ContextHandler contentNotFoundContext = new ContextHandler(server,"/testGetContentNotFound");
contentNotFoundContext.setHandler(t.new TestGetContentNotFoundHandler()); HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { contentOkContext, contentErrorContext, contentNotFoundContext});
server.setHandler(handlers); server.setStopAtShutdown( true );
server.start();
} @Test
public void testGetContentOk()
throws Exception
{
String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentOk" ) );
assertEquals( "It works", result );
} @Test
public void testGetContentError()
throws Exception
{
String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentError/" ) );
assertNull( result );
} @Test
public void testGetContentNotFound()
throws Exception
{
String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentNotFound" ) );
assertNull( result );
} @AfterClass
public static void tearDown()
{
// Do nothing becuase the Jetty server is configured
// to stop at shutdown.
System.out.println("====================After Class=====================");
} /**
* 正常请求处理器
*/
private class TestGetContentOkHandler
extends AbstractHandler
{ @Override
protected void doStart() throws Exception {
super.doStart();
} @Override
public void setServer(Server server) {
super.setServer(server);
} @Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
System.out.println("======================TestGetContentOkHandler=======================");
OutputStream out = response.getOutputStream();
ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
writer.write( "It works" );
writer.flush();
response.setIntHeader( HttpHeaders.CONTENT_LENGTH, writer.size() );
writer.writeTo( out );
out.flush();
request.setHandled(true);
}
} /**
* 异常请求处理器
*/
private class TestGetContentServerErrorHandler
extends AbstractHandler
{
@Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
response.sendError( HttpServletResponse.SC_SERVICE_UNAVAILABLE );
}
} /**
* 404处理器
*/
private class TestGetContentNotFoundHandler
extends AbstractHandler
{ @Override
public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
response.sendError( HttpServletResponse.SC_NOT_FOUND );
}
}
}

直接运行该类,结果为:

junit使用stub进行单元测试的更多相关文章

  1. [Java SE/Junit] 基于Java的单元测试框架Mockito

    Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为. 1 为什么要使用Mockito? Mock可以理解为创建一个虚假的对象,或者说模拟出一个对象.在测试环境中用来替换掉真实 ...

  2. 使用Junit等工具进行单元测试

    一.类的定义: 类是同一事物的总称,类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类. 二.Junit工具的使用: 1.首先新建一个项目叫JUnit_Test,我们编写一个 ...

  3. (转)Eclipse中junit框架的使用——单元测试

    [转]junit浅学笔记一 JUnit是一个回归测试框架(regression testing framework).Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How ...

  4. JUnit基础及第一个单元测试实例(JUnit3.8)

    单元测试 单元测试(unit testing) ,是指对软件中的最小可测试单元进行检查和验证. 单元测试不是为了证明您是对的,而是为了证明您没有错误. 单元测试主要是用来判断程序的执行结果与自己期望的 ...

  5. 单元测试系列:如何使用JUnit+JaCoCo+EclEmma完成单元测试

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢!   原文链接:http://www.cnblogs.com/zishi/p/6726664.html -----如 ...

  6. Maven下使用Junit对Spring进行单元测试

    主要步骤 1. 在工程的pom文件中增加spring-test的依赖: <dependency> <groupId>org.springframework</groupI ...

  7. 阿里知识储备之二——junit学习以及android单元测试

    一,junit框架 http://blog.csdn.net/afeilxc/article/details/6218908 详细见这篇博客 juit目前已经可以和maven项目进行集成和测试,而且貌 ...

  8. junit配合catubuter统计单元测试的代码覆盖率

    1.视频参考孔浩老师ant视频笔记 对应的build-junit.xml脚步如下所示: <?xml version="1.0" encoding="UTF-8&qu ...

  9. 使用Junit对Spring进行单元测试实战小结

    Demo代码: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:/ ...

  10. 使用JUnit 和Jacoco进行单元测试

    Jacoco配置 <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven ...

随机推荐

  1. [转帖]能使 Oracle 索引失效的六大限制条件

    Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时候却适得其反. 例如一张表中有上百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这可能是 oracle 索引失效造成的.or ...

  2. Nginx日志规则以及根据日志进行性能问题判断的思路

    Nginx日志规则以及根据日志进行性能问题判断的思路 背景 Nginx是开源方案里面能实现反向代理 负载均衡的首选. 但是有时候性能出问题比较难以分析和定位, 不知道是不是nginx的瓶颈 性能问题的 ...

  3. SQLServer数据库优化学习-总结

    SQLServer数据库优化学习-总结 背景 各种能力都需要提升. 最近总是遇到SQLServer的问题 趁着周末进行一下学习与提高. 安装与优化 1. 数据库必须安装 64位, 不要安装成32位的版 ...

  4. [转帖]Welcome to the di-kafkameter wiki!

    https://github.com/rollno748/di-kafkameter/wiki#producer-elements Introduction DI-Kafkameter is a JM ...

  5. [转帖]LTP测试

    https://zhuanlan.zhihu.com/p/381538099   整体测试 直接运行runltp命令,将测试/opt/ltp/scenario_groups/default文件中所有的 ...

  6. [转帖]BF16 与 FP16 在模型上哪个精度更高呢

    https://zhuanlan.zhihu.com/p/449345588 BF16 是对FP32单精度浮点数截断数据,即用8bit 表示指数,7bit 表示小数. FP16半精度浮点数,用5bit ...

  7. 基于CefSharp开发浏览器(十)浏览器CefSharp.Wpf中文输入法偏移处理

    一.前言 两年多来未曾更新博客,最近一位朋友向我咨询中文输入法问题.具体而言,他在使用CefSharp WPF版本时遇到了一个问题,即输入法突然出现在屏幕的左上角.在这里记录下处理这个问题的过程,希望 ...

  8. 京音平台-一起玩转SCRM之电销系统

    作者:京东科技 李良文 一.前言 电销是什么?就是坐席拿着电话给客户打电话吗?no no no,让我们一起走进京音平台之电销系统. 京音平台2020年初开始建设,过去的两年多的时间里,经历了跌宕起伏, ...

  9. 记一次 .NET某工控自动化系统 崩溃分析

    一:背景 1. 讲故事 前些天微信上有位朋友找到我,说他的程序偶发崩溃,分析了个把星期也没找到问题,耗费了不少人力物力,让我能不能帮他看一下,给我申请了经费,哈哈,遇到这样的朋友就是爽快,刚好周二晚上 ...

  10. echarts中坐标与标签刻度对齐

    xAxis: { data: ["土地.房屋及建筑物", "遇用设备", "遇用设备", "裤子", "家具. ...