javascript - 如何使用 jasmine 测试已完成和失败的延迟对象

标签 javascript jquery post jasmine

这是有关 javascript 提交请求的代码 (1)。
下面是使用 jasmine 模拟 ajax 请求的测试(2)。

我想模拟服务器行为。有什么想法吗?
有关详细信息,请参阅 (1) 和 (2) 中的注释。

附注:
实际上,在这两种情况下,都会调用 fakeFunction 的完成和失败延迟对象。

<小时/>

(1)

submitForm: function () {
     // the server execute fail only if message.val() is empty
     // and I would like to mock this behaviour in (2)
     backendController.submitForm(message.val()).done(this.onSuccess).fail(this.onError);
},

backendController.submitForm = function (message) {
    return $.ajax({
        url: 'some url',
        type: 'POST',
        dataType: 'json',
        data: {
            message: message
        }
    }).done(function () {
        //some code;
    });
};
<小时/>

(2)

describe('When Submit button handler fired', function () {
    var submitFormSpy,
        fakeFunction = function () {
            this.done = function () {
                return this;
            };
            this.fail = function () {
                return this;
            };
            return this;
        };

    beforeEach(function () {
        submitFormSpy = spyOn(backendController, 'submitForm').andCallFake(fakeFunction);
    });

    describe('if the message is empty', function () {
        beforeEach(function () {
            this.view.$el.find('#message').text('');
            this.view.$el.find('form').submit();
        });
        it('backendController.submitForm and fail Deferred Object should be called', function () {
            expect(submitFormSpy).toHaveBeenCalled();
            // how should I test that fail Deferred Object is called?
        });
    });

    describe('if the message is not empty', function () {
        beforeEach(function () {
            this.view.$el.find('#message').text('some text');
            this.view.$el.find('form').submit();
        });
        it('backendController.submitForm should be called and the fail Deferred Object should be not called', function () {
            expect(submitFormSpy).toHaveBeenCalled();
            // how should I test that fail Deferred Object is not called?
        });
    });

});

最佳答案

我们实际上遇到了同样的问题,试图测试代表 AJAX 模板脚本的延迟对象以进行动态模板化。我们的测试解决方案涉及使用 Jasmine-Ajax库与 Jasmine 本身结合使用。

所以可能会是这样的:

describe('When Submit button handler fired', function () {
  jasmine.Ajax.useMock();

  describe('if the message is empty', function () {

    beforeEach(function() {
      spyOn(backendController, 'submitForm').andCallThrough();
      // replace with wherever your callbacks are defined
      spyOn(this, 'onSuccess');
      spyOn(this, 'onFailure');
      this.view.$el.find('#message').text('');
      this.view.$el.find('form').submit();
    });

    it('backendController.submitForm and fail Deferred Object should be called', function () {
      expect(backendController.submitForm).toHaveBeenCalledWith('');
      mostRecentAjaxRequest().response({
        status: 500, // or whatever response code you want
        responseText: ''
      });

      expect( this.onSuccess ).not.toHaveBeenCalled();
      expect( this.onFailure ).toHaveBeenCalled();
    });
});

另一件事,如果可以的话,尝试分解功能,这样就不会在一次测试中测试整个 DOM 到响应回调路径。如果您足够细粒度,您实际上可以通过在测试中使用延迟对象本身来测试异步延迟解析!

关键是在测试本身中实际使用 Deferred 对象,以便 expect 调用的范围仍在您的 it 功能 block 内。

describe('loadTemplate', function() {
  it('passes back the response text', function() {
    jasmine.Ajax.mock();
    loadTemplate('template-request').done(function(response) {
      expect(response).toBe('foobar');
    });
    mostRecentAjaxRequest().response({ status:200, responseText:'foobar' });
  });
});

关于javascript - 如何使用 jasmine 测试已完成和失败的延迟对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12080087/

相关文章:

php - 传递 WordPress 类别下拉列表中的选定值

jquery - 使用 formdata 发布数组

javascript - 是否可以使用扩展运算符更新对象,而不是创建新对象?

javascript - 滚动之后的侧边栏,但如果高于视口(viewport)则滚动自身

jquery - 危险的刷卡者;即时调整选项?

jquery - removeClass 不适用于两个元素

node.js - 类型错误 : Cannot read property 'headers' of null! MEAN 堆栈

javascript - react : Loading gapi and currentUser on page load

javascript - JSON日期,显示服务器时区的原始日期

jquery - 如何将无序列表 move 到 JQuery 页面上的新部分?