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. [转帖]一文深度讲解JVM 内存分析工具 MAT及实践(建议收藏)

    https://juejin.cn/post/6911624328472133646 1. 前言 熟练掌握 MAT 是 Java 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手, ...

  2. [转帖]细说ASCII、GB2312/GBK/GB18030、Unicode、UTF-8/UTF-16/UTF-32编码

    参考: <编码标准-GB2312 GBK GB18030> <字符编码笔记:ASCII,Unicode 和 UTF-8> <字体编辑用中日韩汉字Unicode编码表> ...

  3. [转帖]Nacos使用2.0.1版本启动出现9848端口错误的解决方式(亲测有效)

    目录 一.背景 二.报错如下 三.报错原因 四.解决方式 一.背景 nacos服务端和客户端都是 2.x版本. centos7使用原始安装nacos单机版,没有使用docker安装naocs集群. 二 ...

  4. [转帖]TiDB 配置参数修改与系统变量修改步骤

    https://tidb.net/blog/bda86911   注意事项1:tidb-test 为集群名称   注意事项2:参数修改前与修改后备份.tiup目录   注意事项3:通过 tiup cl ...

  5. lightning 导入数据库表的操作步骤

    lightning 导入数据库表的操作步骤 TiDB数据库备份恢复的方式与方法 1. mysqldumper 以及 mysql 导入 2. select into outfile 以及 load da ...

  6. [转帖]分析redis 大key

    http://www.lishuai.fun/2023/05/05/redis-bigkey/#/%E5%AE%89%E8%A3%85 redis-rdb-tools 是一个 python 的解析 r ...

  7. [转帖]Linux命令拾遗-硬件资源观测

    https://www.cnblogs.com/codelogs/p/16060455.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 这是Linux ...

  8. K3S +Helm+NFS最小化测试安装部署只需十分钟

    作者:郝建伟 k3s 简介 官方文档:k3s 什么是k3s k3s 是一个轻量级的 Kubernetes 发行版 它针对边缘计算.物联网等场景进行了高度优化. k3s 有以下增强功能: 打包为单个二进 ...

  9. R2M分布式锁原理及实践

    作者:京东科技 张石磊 1 案例引入 名词简介: 资源:可以理解为一条内容,或者图+文字+链接的载体. 档位ID: 资源的分类组,资源必须归属于档位. 问题描述:当同一个档位下2条资源同时审批通过时, ...

  10. ts函数讲解与不确定参数是否使用以及限制返回类型

    1.声明式函数 函数有两个参数 参数的数据类型是 string number 返回值值 number 哈 function person(name: string, age: number): num ...