折騰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%通過了,也有可能實際上是錯的。
- 要注意找問題的方法,把過程詳細的一條條寫出來,然後思考在這些過程中哪裡會出問題?