鍍金池/ 問(wèn)答/測(cè)試  網(wǎng)絡(luò)安全  HTML/ Jest無(wú)法加載script標(biāo)簽內(nèi)容, 導(dǎo)致無(wú)法測(cè)試jsonp

Jest無(wú)法加載script標(biāo)簽內(nèi)容, 導(dǎo)致無(wú)法測(cè)試jsonp

問(wèn)題描述

使用Jest框架測(cè)試一段jsonp的代碼, 但是Jest使用的JsDom好像無(wú)法加載script標(biāo)簽的內(nèi)容, 導(dǎo)致jsonp的全局函數(shù)無(wú)法被調(diào)用. 故不能很好的對(duì)這段jsonp進(jìn)行單側(cè).

jsonp的代碼如下:

function noop(){}

/**
 * @description 序列化數(shù)據(jù)
 */
function formatParams(data) {
  let arr = [];
  for (let name in data) {
    arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
  }
  return arr.join("&");
}

/**
 * @description jsopn請(qǐng)求函數(shù)
 * @param {string} url: 請(qǐng)求地址
 * @param {object} opts: 請(qǐng)求配置項(xiàng)
 *  {object}} parmas: 動(dòng)參請(qǐng)求數(shù)據(jù)的對(duì)象
 *  {number} timeout: 延遲的時(shí)間
 * @param {function} fn 回調(diào)函數(shù), 參數(shù)分別為rr, data
 */

function jsonp(url, opts, fn){
  // 獲取隨機(jī)數(shù)
  const random = Math.random().toString().replace('.', '');
  // 基礎(chǔ)的回調(diào)名稱(chēng)
  const baseCbName = '__onDWGetData__'
  // 獲取了隨機(jī)數(shù)后的回調(diào)名稱(chēng)
  const id = baseCbName + random;
  // 需要被添加到參數(shù)字符串的后綴, 動(dòng)態(tài)參數(shù)會(huì)根據(jù)jsonpCallback的值返回函數(shù)名
  const suffix = '&jsonpCallback=' + baseCbName + random;
  // 進(jìn)行數(shù)據(jù)的序列化, 隨后添加上&jsonpCallback的后綴
  const param = formatParams(opts.data) + suffix;
  // 生成script標(biāo)簽的url, https://dw-online.ksosoft.com/api/dynamicParam/v1/app/appKey + '?' + 序列化的參數(shù) 
  url += '?' + param;
  // 延遲
  const timeout = null != opts.timeout ? opts.timeout : 60000;
  const target = document.head;
  let script;
  let timer;

  if (timeout) {
    timer = setTimeout(function(){
      cleanup();
      if (fn) fn(new Error('ReqDynamic params Timeout'));
    }, timeout);
  }

  function cleanup(){
    if (script.parentNode) script.parentNode.removeChild(script);
    window[id] = noop;
    if (timer) clearTimeout(timer);
  }

  function cancel(){
    if (window[id]) {
      cleanup();
    }
  }

  window[id] = function(data){
    cleanup();
    console.log('window全局調(diào)用了函數(shù):', fn, data);
    if (fn) fn(null, data);
  };

  // 創(chuàng)建腳本
  script = document.createElement('script');
  script.src = url;
  target.parentNode.insertBefore(script, target);

  return cancel;
}

export { jsonp };

測(cè)試的偽代碼代碼如下:

import { jsonp } from '../src/jsonP';
test('模擬jsonp實(shí)現(xiàn)', done => {
  jsonp('https://fake-collect.com', {a: 'b'}, (err, data) => {
    expect(data).toBeTruthy();
    done();
  })
})

但是每次都會(huì)拋出jsonp代碼中的Error: ReqDynamic params Timeout錯(cuò)誤, 該錯(cuò)誤代表請(qǐng)求超時(shí). 表明script無(wú)法被正確的加載導(dǎo)致.

期望結(jié)果

能夠在Jest框架中正確的運(yùn)行jsonp的整個(gè)過(guò)程, 加載script`標(biāo)簽和全局函數(shù)被調(diào)用的過(guò)程

回答
編輯回答
寫(xiě)榮

jest.timeout設(shè)置一個(gè)更長(zhǎng)的數(shù)字

2017年6月29日 13:14