亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

如何模擬一個(gè)XMLHttpRequest請(qǐng)求用于單元測(cè)試——nise源碼閱讀與分析

KevinYan / 3262人閱讀

摘要:概述在我們進(jìn)行單元測(cè)試的過(guò)程中,如果我們需要對(duì)一些接口進(jìn)行相關(guān)的業(yè)務(wù)測(cè)試,那么我們就需要來(lái)模擬請(qǐng)求的發(fā)送與響應(yīng),否則我們就無(wú)法完成測(cè)試的閉環(huán)。我們?cè)偻ㄟ^(guò)記錄的數(shù)據(jù),組合其他的單元測(cè)試框架來(lái)對(duì)業(yè)務(wù)代碼進(jìn)行測(cè)試。

概述

在我們進(jìn)行單元測(cè)試的過(guò)程中,如果我們需要對(duì)一些HTTP接口進(jìn)行相關(guān)的業(yè)務(wù)測(cè)試,那么我們就需要來(lái)模擬HTTP請(qǐng)求的發(fā)送與響應(yīng),否則我們就無(wú)法完成測(cè)試的閉環(huán)。

目前,有許許多多的測(cè)試框架都提供了模擬HTTP請(qǐng)求相關(guān)的一些流程功能,我們?cè)谶@邊文章中將會(huì)講到的,就是我們?cè)谏弦黄P(guān)于單元測(cè)試的博客提高代碼質(zhì)量——使用Jest和Sinon給已有的代碼添加單元測(cè)試中提到的Sinon中引用的HTTP模擬框架nise。

本文的目標(biāo)是讓讀者能夠通過(guò)這篇文章,知道一個(gè)成熟的測(cè)試框架是如何來(lái)模擬一個(gè)HTTP的實(shí)現(xiàn),并且與業(yè)務(wù)代碼進(jìn)行結(jié)合,輔助進(jìn)行測(cè)試。本文內(nèi)容相對(duì)較為簡(jiǎn)單,基本沒(méi)有難度,作為一個(gè)知識(shí)面擴(kuò)充建議讀者快速略讀。

通過(guò)本文,你可以了解以下內(nèi)容:

nise是什么?

nise的設(shè)計(jì)思路是怎么樣?

nise是如何與業(yè)務(wù)代碼結(jié)合,輔助測(cè)試?

nise是什么
fake XHR and Server.

nise在Github上面的介紹很簡(jiǎn)單,雖然只有四個(gè)單詞,但是卻很精確的說(shuō)明了這個(gè)庫(kù)的含義——構(gòu)造一個(gè)模擬的XHR和Server對(duì)象,用來(lái)替換原生的對(duì)象用來(lái)滿(mǎn)足測(cè)試需求。

它是Sinon.js的一部分,用來(lái)處理HTTP相關(guān)測(cè)試問(wèn)題。

該庫(kù)提供了替換原生的XHR對(duì)象和Server相關(guān)的接口,但是我們?cè)诒疚闹兄唤榻B關(guān)于XHR部分,也就是瀏覽器中的XHR對(duì)象的替換。該部分位于倉(cāng)庫(kù)中/lib/fake-xhr/index.js中,下文中提到的nise如果沒(méi)有特別注明,均表示nise中的XHR。

nise的設(shè)計(jì)思路是怎么樣的 nise的API接口與使用方法

想要了解nise的設(shè)計(jì)思路,我們就需要先看下nise的使用方法。

目前,nise提供了以下三個(gè)API接口:

module.exports = {
    xhr: sinonXhr, // 用來(lái)存儲(chǔ)原來(lái)的XHR對(duì)象和一些環(huán)境判斷屬性
    FakeXMLHttpRequest: FakeXMLHttpRequest, // XHR對(duì)象構(gòu)造函數(shù)
    useFakeXMLHttpRequest: useFakeXMLHttpRequest //調(diào)用后,使用fake XHR對(duì)象替換全局,并返回一個(gè)帶有restore方法的fake XHR對(duì)象構(gòu)造函數(shù)
};

我們?cè)谑褂脮r(shí),只需調(diào)用userFakeXMLHttpRequest方法,即可將原生的XHR對(duì)象替換成nise提供的XHR對(duì)象。在測(cè)試完成后,我們?cè)僬{(diào)用返回的restore方法,這樣我們就恢復(fù)了原生的XHR對(duì)象。

返回的模擬HXR對(duì)象還有部分API接口可以調(diào)用,這部分我們將在下一節(jié)——nise結(jié)構(gòu)中進(jìn)行介紹。

nise結(jié)構(gòu) 構(gòu)造函數(shù)——FakeXmlHttpRequest
// 構(gòu)造函數(shù),用來(lái)存儲(chǔ)請(qǐng)求相關(guān)的數(shù)據(jù)如請(qǐng)求狀態(tài)、請(qǐng)求頭等
function FakeXMLHttpRequest(config) {
    EventTargetHandler.call(this);
    this.readyState = FakeXMLHttpRequest.UNSENT; // 原生屬性,用來(lái)標(biāo)識(shí)請(qǐng)求狀態(tài)
    this.requestHeaders = {}; // 記錄請(qǐng)求headers屬性
    this.requestBody = null; // 記錄請(qǐng)求body屬性
    this.status = 0;
    this.statusText = "";
    this.upload = new EventTargetHandler(); // 上傳事件屬性
    this.responseType = ""; // 響應(yīng)類(lèi)型屬性
    this.response = ""; // 響應(yīng)內(nèi)容屬性
    this.logError = configureLogError(config);

    if (sinonXhr.supportsTimeout) {
        this.timeout = 0;
    }

    if (sinonXhr.supportsCORS) {
        this.withCredentials = false;
    }

    if (typeof FakeXMLHttpRequest.onCreate === "function") {
        FakeXMLHttpRequest.onCreate(this);
    }
}

FakeXMLHttpRequest.useFilters = false;

FakeXMLHttpRequest.addFilter = function addFilter(fn) {} // 增加過(guò)濾函數(shù)

FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {} // 將常用事件如open、send等XHR的方法綁定到模擬的XHR對(duì)象上

FakeXMLHttpRequest.parseXML = function parseXML(text) {} // 解析XML

extend(FakeXMLHttpRequest.prototype, sinonEvent.EventTarget, {
    open: function open(method, url, async, username, password) {} // XHR原生方法模擬
    
    readyStateChange: function readyStateChange(state) {} // XHR原生方法模擬
    
    setRequestHeader: function setRequestHeader(header, value) {} // 設(shè)置請(qǐng)求header并保存到requestHeaders屬性中
    
    setStatus: function setStatus(status) {} // 設(shè)置status并保存到status屬性中
    
    setResponseHeaders: function setResponseHeaders(headers) {} // 設(shè)置響應(yīng)headers并跟隨callback一起返回
    
    send: function send(data) {} // XHR原生方法模擬
    
    abort: function abort() {} // 終止HTTP請(qǐng)求
    
    error: function () {} // XHR原生方法模擬
    
    triggerTimeout: function triggerTimeout() {} // 觸發(fā)超時(shí)
    
    getResponseHeader: function getResponseHeader(header) {} // 獲取響應(yīng)header
    
    getAllResponseHeaders: function getAllResponseHeaders() {} // 獲取全部的響應(yīng)headers
    
    setResponseBody: function setResponseBody(body) {} // 設(shè)置響應(yīng)內(nèi)容
    
    respond: function respond(status, headers, body) {} // 觸發(fā)請(qǐng)求的callback函數(shù)
    
    uploadProgress: function uploadProgress(progressEventRaw) {} // 上傳進(jìn)度觸發(fā)事件
    
    downloadProgress: function downloadProgress(progressEventRaw) {} // 下載進(jìn)度觸發(fā)事件
    
    uploadError: function uploadError(error) {} // 上傳失敗觸發(fā)事件
    
    overrideMimeType: function overrideMimeType(type) {} // 覆蓋mineType
});
nise是如何與業(yè)務(wù)代碼結(jié)合,輔助測(cè)試

通過(guò)上面的源碼介紹我們可以知道:nise是通過(guò)完全模擬一個(gè)模擬的XHR對(duì)象,然后再使用這個(gè)模擬的XHR對(duì)象來(lái)替換全局的XHR對(duì)象。

而我們?cè)谶M(jìn)行HTTP相關(guān)測(cè)試時(shí),參數(shù)是由我們傳入的,因此不需要進(jìn)行驗(yàn)證。所以我們最終需要驗(yàn)證的其實(shí)是callback中的處理邏輯和結(jié)果。因此,我們可以通過(guò)以下一個(gè)示例來(lái)看下它如何與業(yè)務(wù)代碼進(jìn)行結(jié)合。這個(gè)示例是在上一篇博客中出現(xiàn)過(guò)的示例:

test("user", () => {
    let callback = jest.fn();

    HTTPCommon.deleteRemoteSession({
        data: {},
        success: callback
    });

    expect(requests.length).toBe(1);

    requests[0].respond(200, {"Content-Type": "application/json"}, "hjava"); // 模擬返回值

    expect(callback.mock.calls[0][0]).toBe("hjava");
});

通過(guò)respond這個(gè)方法,fakeXMLHttpRequest對(duì)象觸發(fā)了callback函數(shù),并且將指定數(shù)據(jù)傳遞到業(yè)務(wù)代碼中。因此,我們能夠通過(guò)callback相關(guān)的業(yè)務(wù)邏輯來(lái)判斷我們的邏輯是否正常。

總結(jié)

nise通過(guò)一個(gè)非常常規(guī)的方法——模擬一個(gè)XHR對(duì)象并且實(shí)現(xiàn)XHR對(duì)象的所有功能來(lái)完成針對(duì)HTTP請(qǐng)求進(jìn)行記錄的功能。我們?cè)偻ㄟ^(guò)nise記錄的數(shù)據(jù),組合其他的單元測(cè)試框架來(lái)對(duì)業(yè)務(wù)代碼進(jìn)行測(cè)試。

nise的源碼只有600余行,而且非常簡(jiǎn)單易懂。我將原有代碼folk一份并加上了部分注釋?zhuān)信d趣的同學(xué)可以看看,具體地址見(jiàn)此處。

附錄

Sinon.js

nise

我folk的nise

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/94510.html

相關(guān)文章

  • 提高代碼質(zhì)量——使用Jest和Sinon給已有的代碼添加單元測(cè)試

    摘要:現(xiàn)在,我們可以使用單元測(cè)試來(lái)提高自己的代碼質(zhì)量。它在單元測(cè)試的編寫(xiě)中通常用來(lái)模擬等相關(guān)請(qǐng)求。通過(guò)這篇文章,你應(yīng)該學(xué)會(huì)了如何針對(duì)已有代碼從零開(kāi)始編寫(xiě)一套完整的單元測(cè)試用例。 概述 在日常的功能開(kāi)發(fā)中,我們的代碼測(cè)試都依賴(lài)于自己或者QA進(jìn)行測(cè)試。這些操作不僅費(fèi)時(shí)費(fèi)力,而且還依賴(lài)開(kāi)發(fā)者自身的驅(qū)動(dòng)。在開(kāi)發(fā)一些第三方依賴(lài)的庫(kù)時(shí),我們也沒(méi)有辦法給第三方提供完整的代碼質(zhì)量報(bào)告。 現(xiàn)在,我們可以使用單...

    voyagelab 評(píng)論0 收藏0
  • Ajax單元測(cè)試傻瓜教程

    摘要:原文出處單元測(cè)試傻瓜教程請(qǐng)求經(jīng)常容易發(fā)生錯(cuò)誤,客戶(hù)端發(fā)送的數(shù)據(jù)出問(wèn)題,服務(wù)器端返回的數(shù)據(jù)有誤都會(huì)導(dǎo)致請(qǐng)求錯(cuò)誤。設(shè)置在我們開(kāi)始單元測(cè)試之前,我們需要安裝幾個(gè)必須的工具。我們將用它來(lái)向你們展示如何對(duì)進(jìn)行單元測(cè)試。 原文出處 :AJAX單元測(cè)試傻瓜教程 Ajax 請(qǐng)求經(jīng)常容易發(fā)生錯(cuò)誤,客戶(hù)端發(fā)送的數(shù)據(jù)出問(wèn)題,服務(wù)器端返回的數(shù)據(jù)有誤都會(huì)導(dǎo)致 Ajax 請(qǐng)求錯(cuò)誤。你不能保證與服務(wù)器的連接總是工作...

    30e8336b8229 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<