1. 程式人生 > >折騰nock給jsonp進行單元測試

折騰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響應啊啊啊啊。

我學到了什麼?

  1. 對jsonp的原理有了更深的理解。jsonp不能在node端進行單元測試。
  2. 就算單元測試100%通過了,也有可能實際上是錯的。
  3. 要注意找問題的方法,把過程詳細的一條條寫出來,然後思考在這些過程中哪裡會出問題?