模擬化 ajax

測試 ajax 呼叫

我們寫了一款名為 jasmine-ajax 的外掛程式,可在測試中模擬 ajax 呼叫。要使用這款外掛程式,您需要下載 mock-ajax.js 檔案並將其新增到 jasmine 輔助程式,以便在使用它的任何規格之前載入它。

describe("mocking ajax", function() {

整個測試集的基本使用

    describe("suite wide usage", function() {

當您要在整個測試集中模擬所有 ajax 呼叫時,請在 beforeEach 中使用 install()

        beforeEach(function() {
            jasmine.Ajax.install();
        });

由於 jasmine-ajax 會對頁面的全域 XMLHttpRequest 進行存根化,因此您會想要在 afterEachuninstall(),以便規格或設定會希望執行實際的 ajax 要求。

        afterEach(function() {
            jasmine.Ajax.uninstall();
        });

        it("specifying response when you need it", function() {
            const doneFn = jasmine.createSpy("success");

像往常一樣製作您的要求。Jasmine-Ajax 在 XMLHttpRequest 物件中模擬您的要求,因此應該與執行 ajax 要求的其他函式庫相容。

            const xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(args) {
                if (this.readyState == this.DONE) {
                    doneFn(this.responseText);
                }
            };

            xhr.open("GET", "/some/cool/url");
            xhr.send();

在這個時間點,ajax 要求尚未傳回,因此可在此執行任何關於中間狀態(如 spinner)的聲明。

            expect(jasmine.Ajax.requests.mostRecent().url)
                .toBe('/some/cool/url');
            expect(doneFn).not.toHaveBeenCalled();

現在我們告訴要求其回應應有的樣子

            jasmine.Ajax.requests.mostRecent().respondWith({

HTTP 回應代碼

                "status": 200,

您也可以指定回應的內容類型

                "contentType": 'text/plain',

要傳回的 responseText,它應為字串。

                "responseText": 'awesome response'
            });

在我們告知要求回應後,我們的回呼會被呼叫。

            expect(doneFn).toHaveBeenCalledWith('awesome response');
        });

您也可以預先指定回應,當要求發布時,它們會立即回應。

        it("allows responses to be setup ahead of time", function () {
            const doneFn = jasmine.createSpy("success");

使用您要立即傳回的 URL 來呼叫 stubRequest。然後 andReturn 會收到與 respondWith 相同類型的引數。

            jasmine.Ajax.stubRequest('/another/url').andReturn({
                "responseText": 'immediate response'
            });

像往常一樣製作您的要求

            const xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(args) {
                if (this.readyState == this.DONE) {
                    doneFn(this.responseText);
                }
            };

            xhr.open("GET", "/another/url");
            xhr.send();

            expect(doneFn).toHaveBeenCalledWith('immediate response');
        });
    });

如果您只想在單一規格中使用它,可以使用 withMockwithMock 會採用一個函式,該函式會在 ajax 被模擬化後呼叫,而模擬化會在這個函式完成後解除安裝。

    it("allows use in a single spec", function() {
        const doneFn = jasmine.createSpy('success');
        jasmine.Ajax.withMock(function() {
            const xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function(args) {
                if (this.readyState == this.DONE) {
                    doneFn(this.responseText);
                }
            };

            xhr.open("GET", "/some/cool/url");
            xhr.send();

            expect(doneFn).not.toHaveBeenCalled();

            jasmine.Ajax.requests.mostRecent().respondWith({
                "status": 200,
                "responseText": 'in spec response'
            });
    
            expect(doneFn).toHaveBeenCalledWith('in spec response');
        });
    });
});