【问题标题】:Jasmine Jquery Spy AJAX complete functionJasmine Jquery Spy AJAX完整功能
【发布时间】:2018-04-12 04:01:48
【问题描述】:

我正在尝试编写单元测试来覆盖方法 A complete() 块。我可以使用 Deferred 模拟 ajax 请求。但是 Deferred 不支持 complete() 所以我遇到了错误 TypeError: _this.methodB(...).complete 不是函数。请帮我覆盖 methodB(..).complete() 块。

    methodB: function(xURL, container) {
    var _this = this;
    return $.ajax({

    type: 'GET',
    url: xURL,
    async: false,
    dataType: 'html',
    timeout: _this.ajaxTimeOut
    })
    .fail(function(resp) {
    _this.doSomethingOnFail();
    })
    .done(function(resp, textStatus, jqXHR) {
        if (jqXHR.status === 200 && resp !== '') {
           _this.doSomethingOnDone();       
     }              
  });
},
    methodA: function(e) {
    var _this = this,
   _this.methodB(_this.refineURL, _this.$el)
   .complete(function(resp) {
    **if (resp.responseText !== undefined && 
        resp.responseText.indexOf("PRICE_DATA_AVLBL = 'false'") > -1) {
        var params1 = _this._getFilterURLParameters(_this.refineURL);
        var params2 = _this._getFilterURLParameters(_this.SUCC_URL);

        if (params1.lowerbound !== params2.lowerbound || 
            $(e.currentTarget).hasClass('js-txt-min')) {
            $txtMin.addClass('border-danger');
        } else {
            $txtMin.val(params2.lowerbound);
        }
    } else {
       _this._pageSubmit();
    }**

 });

}

单元测试代码:

  it('validate ajax complete', function ajaxComplete(){
      spyOn($, 'ajax').and.callFake( function fake() {
      XMLHttpRequest = jasmine.createSpy('XMLHttpRequest');      
      var jqXHR = new XMLHttpRequest();
      jqXHR.status = 200;
      var dea = new $.Deferred();    
      dea.resolve('{property:value}',' ', jqXHR);
      return dea;
   });
   f.methodA();
  });

【问题讨论】:

  • 如果你正在测试methodA,你不应该担心methodB的内部结构。你应该嘲笑methodB。见我的answer。

标签: javascript jquery unit-testing jasmine jasmine-jquery


【解决方案1】:

模拟依赖项

重要的是要记住,在测试函数时,您要模拟该函数的依赖关系。您不想在测试中实际调用那些依赖函数,因为您没有测试这些函数。您应该在其他地方测试这些函数,并模拟它们的依赖关系等。

您的代码

在测试methodA 时牢记这一点,您不必关心methodB 制作 ajax 请求。您所关心的只是它返回一些具有complete 函数的对象,并且您正确地连接了一个回调,等等。

测试

以下(未经测试的)代码应该大致适合您,或者给您一个不错的起点。

describe('.methodA()', function() {
  var methodBResult;

  beforeEach(function() {
    methodBResult = jasmine.createSpyObj('result', ['complete']);
    spyOn(f, 'methodB').and.returnValue(methodBResult);
  });

  it('should call .methodB()', function() {
    f.refineURL = 'something for the test';
    f.$el = 'something else for the test';
    f.methodA();
    expect(f.methodB.calls.count()).toBe(1);
    expect(f.methodB).toHaveBeenCalledWith(f.refineURL, f.$el);
  });

  it('should register a callback on complete', function() {
    f.methodA();

    expect(methodBResult.complete.calls.count()).toBe(1);
    expect(methodBResult.complete).toHaveBeenCalledWith(jasmine.any(Function));
  });

  it('should call .doSomethingOnComplete() when the callback is invoked', function() {
    spyOn(f, 'doSomethingOnComplete');

    f.methodA();

    var callback = methodBResult.complete.calls.argsFor(1)[0];    
    callback();

    expect(f.doSomethingOnComplete.calls.count()).toBe(1);
    expect(f.doSomethingOnComplete).toHaveBeenCalledWith();
  });
});

【讨论】:

  • 感谢您的回复。这是一个很好的起点。我正在尝试覆盖使用 resp.responseText 来检查其是否为空的完整块中的代码。
  • 你的问题有点误导。你说你试图覆盖methodA()。此方法是唯一使用complete 块的方法。听起来您确实在尝试涵盖 methodB()。您的示例对完整块中的 resp 也没有任何作用。
  • 很抱歉没有在完整块中包含代码。我对stackoverflow很陌生。这是我需要覆盖的完整块中的代码..complete(function(resp) { if (resp.responseText !== undefined && resp.responseText.indexOf("PRICE_DATA_AVLBL = 'false'") > -1) { } }
  • 我需要覆盖完整块中的条件。所以我正在寻找解决方案来覆盖这个块。我尝试使用 Deferred 但它不支持完整块。非常感谢任何帮助。再次感谢您查看此 @seth 花。
  • 不用担心,请使用您实际尝试测试的代码更新您的问题,并删除您不尝试测试的所有代码(如方法 B 的内容)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 2013-05-20
  • 2014-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多