Полная функция Jasmine Jquery Spy AJAX

Я пытаюсь написать модульный тест, чтобы покрыть метод Блок Complete(). Я могу издеваться над запросом ajax, используя Deferred. Но 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();
  });

person Prashant Sajjan    schedule 31.10.2017    source источник
comment
Если вы тестируете methodA, вам не следует беспокоиться о внутреннем устройстве methodB. Вы должны издеваться над методом B. См. мой ответ.   -  person Seth Flowers    schedule 31.10.2017


Ответы (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();
  });
});
person Seth Flowers    schedule 31.10.2017
comment
Спасибо за ответ. это хорошая отправная точка. Я пытаюсь покрыть код полным блоком, который использует resp.responseText для проверки его пустого или нет. - person Prashant Sajjan; 01.11.2017
comment
Ваш вопрос немного вводит в заблуждение тогда. Вы сказали, что пытаетесь охватить метод A(). Этот метод является единственным методом, который использует блок complete. Похоже, вы действительно пытаетесь охватить метод B(). Ваш пример также ничего не делает с resp в полном блоке. - person Seth Flowers; 01.11.2017
comment
Извините, что не включил код в полный блок. Я новичок в stackoverflow. Это код в полном блоке, который мне нужно охватить. - person Prashant Sajjan; 01.11.2017
comment
Мне нужно покрыть условие if в полном блоке. Поэтому я ищу решение для покрытия этого блока. Я пытался использовать Deferred, но он не поддерживает полную блокировку. Любая помощь очень ценится. еще раз спасибо за внимание к этим цветам @seth. - person Prashant Sajjan; 01.11.2017
comment
Не беспокойтесь, пожалуйста, обновите свой вопрос кодом, который вы на самом деле пытаетесь протестировать, и удалите любой код (например, кишки метода B), который вы не пытаетесь протестировать. - person Seth Flowers; 01.11.2017
comment
Я обновил блок .complete() кодом, который необходимо покрыть. - person Prashant Sajjan; 01.11.2017
comment
Прямо сейчас ваш полный блок не имеет побочных эффектов, поэтому тестировать нечего. У вас просто есть if/else, и ни один из них ничего не делает. - person Seth Flowers; 01.11.2017
comment
in, если установлены атрибуты текстового поля блока. Мне нужно покрыть этот блок - person Prashant Sajjan; 02.11.2017