Использовать jasmine, чтобы ожидать, что функция была назначена переменной?

#javascript #unit-testing #jasmine #ecmascript-6

#javascript #модульное тестирование #jasmine #ecmascript-6

Вопрос:

Возьмем следующий пример класса es6:

 export default class sellerController {
    saveOrUpdate(){
        return this.id ? this.updateSettings.bind(this) : this.saveNewSettings.bind(this);
    }
}
  

Я пытаюсь создать модульный тест для этого метода saveOrUpdateMethod.

 it("Should select between save or update if id is or isn't set", function() {

      var saveOrUpdate = SellerDetailsCtrl.saveOrUpdate();
      expect(saveOrUpdate).toEqual(SellerDetailsCtrl.updateSettings.bind(SellerDetailsCtrl))
    });
  

Но, похоже, это не работает. Ошибка

Ожидаемая функция равна функции.

Возможно ли это вообще? Подтвердите, что я назначил определенную функцию, привязанную к переменной?

Комментарии:

1. как вы решили свою проблему?

Ответ №1:

Поскольку bind всегда возвращается новая анонимная функция, вы можете попробовать сравнить по телу функций:

 var saveOrUpdate = SellerDetailsCtrl.saveOrUpdate();
expect(saveOrUpdate.toString()).toEqual(SellerDetailsCtrl.updateSettings.bind(SellerDetailsCtrl).toString())
  

Однако это только гарантирует, что будет возвращена связанная функция, без понимания, какая функция связана. Таким образом, он не предоставляет возможности проверки конкретной связанной функции.

Лучшим подходом было бы использовать spy :

 spyOn(SellerDetailsCtrl.updateSettings).and.callFake(function() {
    return 'updateSettings';
})

var saveOrUpdate = SellerDetailsCtrl.saveOrUpdate();
expect(saveOrUpdate()).toEqual('updateSettings');
  

Другой альтернативой является переопределение native bind для теста, а затем сброс его обратно на native:

 var native = Function.prototype.bind;

Function.prototype.bind = (function () {
    var originalBind = Function.prototype.bind;
    return function (obj) {
        var bound = originalBind.apply(this, Array.prototype.slice.call(arguments, 1));
        bound.original = this;

        return bound;
    };
}());

var saveOrUpdate = SellerDetailsCtrl.saveOrUpdate();
expect(saveOrUpdate.original).toEqual(SellerDetailsCtrl.updateSettings);

Function.prototype.bind = native;