junit使用stub进行单元测试
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进行单元测试的更多相关文章
- [Java SE/Junit] 基于Java的单元测试框架Mockito
Mockito 是一个模拟测试框架,主要功能是在单元测试中模拟类/对象的行为. 1 为什么要使用Mockito? Mock可以理解为创建一个虚假的对象,或者说模拟出一个对象.在测试环境中用来替换掉真实 ...
- 使用Junit等工具进行单元测试
一.类的定义: 类是同一事物的总称,类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类. 二.Junit工具的使用: 1.首先新建一个项目叫JUnit_Test,我们编写一个 ...
- (转)Eclipse中junit框架的使用——单元测试
[转]junit浅学笔记一 JUnit是一个回归测试框架(regression testing framework).Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How ...
- JUnit基础及第一个单元测试实例(JUnit3.8)
单元测试 单元测试(unit testing) ,是指对软件中的最小可测试单元进行检查和验证. 单元测试不是为了证明您是对的,而是为了证明您没有错误. 单元测试主要是用来判断程序的执行结果与自己期望的 ...
- 单元测试系列:如何使用JUnit+JaCoCo+EclEmma完成单元测试
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6726664.html -----如 ...
- Maven下使用Junit对Spring进行单元测试
主要步骤 1. 在工程的pom文件中增加spring-test的依赖: <dependency> <groupId>org.springframework</groupI ...
- 阿里知识储备之二——junit学习以及android单元测试
一,junit框架 http://blog.csdn.net/afeilxc/article/details/6218908 详细见这篇博客 juit目前已经可以和maven项目进行集成和测试,而且貌 ...
- junit配合catubuter统计单元测试的代码覆盖率
1.视频参考孔浩老师ant视频笔记 对应的build-junit.xml脚步如下所示: <?xml version="1.0" encoding="UTF-8&qu ...
- 使用Junit对Spring进行单元测试实战小结
Demo代码: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:/ ...
- 使用JUnit 和Jacoco进行单元测试
Jacoco配置 <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven ...
随机推荐
- ONVIF网络摄像头(IPC)客户端开发—最简RTSP客户端实现
前言: 网上对于RTSP协议客户端的表述和实现非常不清晰,在实际使用中,FFMPEG和live555这些软件已经实现了RTSP客户端和服务端的所有功能,但是它们并没有将RTSP协议独立出来,通过看li ...
- [转帖]Grafana+influxdb+ntopng简易网络流量分析展示系统
Grafana逼格高,所以用它展示ntopng的数据 >_< 一,ntopng 根据官网资料 https://www.ntop.org/ntop/ntopng-influxdb-and-g ...
- [转帖]Nginx中if语句中的判断条件
https://www.cnblogs.com/songxingzhu/p/6382007.html 一.if语句中的判断条件(nginx) 1.正则表达式匹配: ==:等值比较; ~:与指定正则表达 ...
- [转帖]Nginx reuseport 导致偶发性卡顿
https://github.com/jonmeredith/tcpperf https://plantegg.github.io/2023/06/08/Nginx%20reuseport%20%E5 ...
- [转帖]《AWK程序设计语言》笔记(1)—— AWK入门与简单案例
原文为 <The AWK Programming Language>,GitHub上有中译版,不过有些内容翻译的比较奇怪,建议跟原版对照着看 https://github.com/wuzh ...
- [转帖]Springboot容器化镜像设置堆内存大小
参考资料:Best Practices: Java Memory Arguments for Containers - DZone Java 有三种方式设置最大堆内存大小: 1. -Xmx 2. -X ...
- 【贪心】AGC018C Coins
Problem Link 现在有 \(X+Y+Z\) 个人,第 \(i\) 个人有三个权值 \(a_i,b_i,c_i\),现在要求依次选出 \(X\) 个人,\(Y\) 个人和 \(Z\) 个人(一 ...
- RIPEMD加密技术探究:优势、劣势与实战应用
摘要:RIPEMD加密算法作为一种哈希算法,自1989年诞生以来,因其高效.安全的特性在网络安全领域得到了广泛的应用.本文将对RIPEMD算法的优缺点进行详细分析,并给出一个Java完整的示例代码.同 ...
- Python 潮流周刊第 37 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- openAI发布v0.2.0了
时隔20天,OpenAI从v0.0.1升级到了v0.2.0.与v0.0.1版相比,v0.2.0版主要做了以下改动: 把cmd目录下微信公众号的相关服务迁移到了这里 完善了cmd下的测试服务,针对ope ...