折腾nock给jsonp进行单元测试
概述
前几天学习用Jest和nock.js对异步api进行单元测试。在项目中,我用到了jsonp,自然想到对jsonp进行单元测试。
过程很折腾,结果很有趣。
jsonp.js
首先axios或者fetch都不支持jsonp,就连nodejs内置的http也不支持jsonp,所以要去找一个能发jsonp的库,翻了一下github,觉得jsonp这个库甚好,就用它了。
npm i jsonp
浏览器端与node端
Jest和nock都不支持浏览器端,只能用node端进行单元测试。
写好代码用node index.js运行,发现node端报错,在jsonp里面找不到document对象。
好吧,这是node端,jsonp的原理是用script标签跨域,没有html没有document怎么添加script标签跨域呢?
只好建html然后在浏览器端进行script标签跨域。
好吧,就用create-react-app,还自带jest。
reate-react-app jsonp-test
npm i nock
测试100%通过?
安装完之后就在app.test.js里面写测试代码:
import jsonp from 'jsonp';
import nock from 'nock';
var jsonpData = () => {
    return jsonp(host + url, opts, (err, data) => {
      return data;
    })
}
describe('test-jsonp', () => {
    // 测试nock是否能模拟jsonp
    test('should get successful status', () => {
        const host = '//dora.webcgi.163.com';
        const url = '/api/213_792_2018_09_14/active_check';
        const opts = {
            account: '316547491'
        };
        nock(host)
            .get(url)
            .reply(function(uri, requestBody, cb) {
                setTimeout(function() {
                    cb(null, [201, 'THIS IS THE REPLY BODY'])
                });
            });
        function callback(err, data) {
            expect(data.status).toBe(201);
            done();
        }
        jsonp('//dora.webcgi.163.com/api/213_792_2018_09_14/active_check', opts, callback);
    })
});
然后运行测试,发现100%通过,一片绿字,哇,心里很高兴,nock竟然能测试jsonp,哈哈!!!
再玩玩,修改了一下参数:
expect(1+1).toBe(3);
测试还是100%通过?不可能吧,哪里出了问题。
google没有找到,Jest的资料很少,只能看文档了,文档应该有。把Jest异步api测试文档仔细看了一下,才发现需要在箭头函数的括号里面加入done标记:
import jsonp from 'jsonp';
import nock from 'nock';
var jsonpData = () => {
    return jsonp(host + url, opts, (err, data) => {
      return data;
    })
}
describe('test-jsonp', () => {
    // 测试nock是否能模拟jsonp
    test('should get successful status', done => {
        const host = '//dora.webcgi.163.com';
        const url = '/api/213_792_2018_09_14/active_check';
        const opts = {
            account: '316547491'
        };
        nock(host)
            .get(url)
            .reply(function(uri, requestBody, cb) {
                setTimeout(function() {
                    cb(null, [201, 'THIS IS THE REPLY BODY'])
                });
            });
        function callback(err, data) {
            expect(data.status).toBe(201);
            done();
        }
        jsonp('//dora.webcgi.163.com/api/213_792_2018_09_14/active_check', opts, callback);
    })
});
测试超时?
然后再进行测试,发现,测试超时?为什么http请求发不出去呢?
用react进行本地调用api试了好几次,明明可以啊。
非常摸不着头脑,找不到问题所在,明明发出去了http请求,react里面也能够接收http响应,证明没有被拉黑名单,为什么测试就接收不到http响应呢?
想了半天快要放弃的时候才突然想到,script?是的,jsonp的原理是在html加一个script标签进行跨域,而在node端根本就没有html好吗?自然就接受不到http响应啊啊啊啊。
我学到了什么?
- 对jsonp的原理有了更深的理解。jsonp不能在node端进行单元测试。
- 就算单元测试100%通过了,也有可能实际上是错的。
- 要注意找问题的方法,把过程详细的一条条写出来,然后思考在这些过程中哪里会出问题?
折腾nock给jsonp进行单元测试的更多相关文章
- React单元测试——十八般兵器齐上阵,环境构建篇
		一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套完整的单元测试能在在后续迭代更新中回归错误时候给与警 ... 
- 单元测试地二蛋 先弄个两个原生模块1个原始的一个jq插件
		放羊测试测完了再测这两个瞎搞的下拉列表组建 看看从单元测试模块化的角度组建会写成啥样 1:ajax请求 简单文本 2:1个页面多个实例 3:复杂展示+自定义点击+自定义处理函数 ... 
- Android单元测试实践
		为什么要写单元测试 首先要介绍为什么蘑菇街支付金融这边会采用单元测试的实践.说起来比较巧,刚开始的时候,只是我一个人会写单元测试.后来老板们知道了,觉得这是件 很有价值的事情,于是就叫我负责我们组的单 ... 
- Jsonp post 跨域方案
		近期在项目中遇到这样一问题,关于jsonp跨域问题,get传值是可以的,但post传值死活不行啊,于是网上看了一大堆关于这方面的资料,最终问题得以解决,今天抽空与大家分享下. 说明:http://ww ... 
- jsonp使用规范
		这两天花了很多时间弄研究jsonp这个东西, 可是无论我怎么弄..TMD就是不进入success函数,并且一直进入error函数...让我着实DT啊. 可以看下我之间的提问(这就是我遇到的烦恼).. ... 
- jsonp与cors跨域的一些理解(转)
		CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而这种访问是被同源策略所禁止的. ... 
- 单元测试React
		React单元测试——十八般兵器齐上阵,环境构建篇 一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套 ... 
- 教育单元测试mock框架优化之路(中)
		转载:https://sq.163yun.com/blog/article/169564470918451200 三.间接依赖的bean的mock替换 对于前面提供的@Mock,@Spy+@Injec ... 
- angular5中使用jsonp请求页面
		说多了,都是眼泪,折腾了很久,各种百度,查到的例子,全都报错,可能是因为我的angular的版本太高,向下都不兼容? 我的angular版本为最新的5.2.11: 下面是正确的jsonp请求的方法 1 ... 
随机推荐
- angular如何引入公共JS
			一.现象 在项目的开发中,总会用到一些公司的脚本方法,同时,不希望在每个页面用到时又得需要引用,有点麻烦. 二.解决 1.在src文件夹下新建文件夹 utils: 2.在utils下新建文件 comm ... 
- Hishop数据库根据产品ProductID取产品规格
			#region 产品规格 public static string GetSku(int ProductId) { DataTable skus =GetSkus(ProductId); // Res ... 
- vue项目部署到服务器
			1.配置config目录下index.js index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve ... 
- 分享一个14年写的用户管理类-swift版
			AccountManager类 14年设计,从swift 0.9开始,迭代到现在swift4.0版本,总体几乎没什么改动,简单稳定. 其实现的思路主要还是借助之前net反射的经验,实现了自动保存用户信 ... 
- 能量模型与softmax和RBM以及正态分布的关联
			上面一篇文章中探讨了玻尔兹曼分布的起源: 在不清楚目标的真实分布,也不知道样本分布的时候,假设任意输入与输出组合都是同样可能发生的,这样是最公平,最无偏的先验. 因为无法直接统计出给定任意一种输入x, ... 
- NOIP刷题建议(未完结)
			1NOIP提高组真题 2NOI部分题目 为什么要写这个? 主要是一个人在硕大的机房里打(wan)代(you)码(xi),没多少时间了,所以打算来总结一下. 这个也是为我接下来冲刺做一个准备. 这个会不 ... 
- django中views中方法的request参数
			知其然亦要知其所以然 views每个方法的参数都是request,那么问题来了,request为何物? 首先,几乎每个方法都是取数据(无论是从数据库,还是从第三方接口),然后进行一定的处理,之后传给前 ... 
- C语言闰年问题程序框图
			判定2000-2500年中的每一年是否为闰年,并将结果输出. 先分析闰年成立条件: 1)能被4整除,但不能被100整除的年份都是闰年: (2)能被400整除的年份是闰年: #include<st ... 
- Vscode调试C的多文件工程配置
			关于Vscode的C语言的单文件调试,可以参见VScode调试C语言的设置(win10,Linux),里面已经说明基本的配置和使用. 下面说明一下如何调试多个文件的工程,首先写一个简单的工程,其中工程 ... 
- 2019.03.09 bzoj5371: [Pkusc2018]星际穿越(主席树)
			传送门 题意简述: 给一个序列,对于第iii个位置,它跟[limi,i−1][lim_i,i-1][limi,i−1]这些位置都存在一条长度为111的无向边. 称dist(u,v)dist(u,v) ... 
