模拟 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,您需要在 afterEach 中使用 uninstall(),以便期望发出真实 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 请求尚未返回,因此可以在这里运行有关中间状态(例如加载指示器)的任何断言。

            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');
        });
    });
});