<p>sinon stub - не может заглушить стрелочную функцию в классе</p>

Созданный на 3 сент. 2016  ·  1Комментарий  ·  Источник: sinonjs/sinon

  • Версия Sinon: v2.0.0-pre.2
  • Окружающая среда: Windows 10
  • Другие библиотеки, которые вы используете: Typescript, babel, mocha, chai.

Чего вы ожидали?
Я ожидал, что смогу заглушить стрелочную функцию в классе.

Что на самом деле происходит
Я не могу заглушить функцию стрелки, но могу заглушить функцию прототипа класса.

FAILED TESTS:
  ExampleClass tests
    × should stub thisDoesntWork arrow function
      Chrome 52.0.2743 (Windows 10 0.0.0)
    TypeError: Attempted to wrap undefined property thisDoesntWork as function
        at wrapMethod (webpack:///~/sinon/pkg/sinon.js:3138:0 <- test-bundler.js:7377:21)
        at Object.stub (webpack:///~/sinon/pkg/sinon.js:2472:0 <- test-bundler.js:6711:12)
        at Context.<anonymous> (webpack:///src/stores/sinon.test.ts:22:51 <- test-bundler.js:96197:72)

Как воспроизвести

export class ExampleClass {
    thisWorks() {
        return 0;
    }

    thisDoesntWork = () => {
        return 0;
    }
}

describe("ExampleClass tests", () => {
    it("should stub thisWorks function", () => {
        let stubFunctionA = sinon.stub(ExampleClass.prototype, "thisWorks");
    });
    it("should stub thisDoesntWork arrow function", () => {
        let stubFunctionB = sinon.stub(ExampleClass, "thisDoesntWork");
    });
});
Documentation ES2015+

Самый полезный комментарий

Это пища для предстоящего нового сайта документации, где мы надеемся опубликовать еще несколько статей, ориентированных на обучение, по заглушкам, шпионажу и т. Д. В контексте ES2015.

Обычно, когда вы сталкиваетесь с подобными проблемами, очень полезно помнить один простой факт: ES2015 часто является просто синтаксическим сахаром поверх простых конструкций ES5. Это означает, что если вы не понимаете, почему что-то происходит (или не происходит), попробуйте деконструировать код до его эквивалента в ES5. Самый простой способ (это то, что я только что сделал) - просто вставить пример кода на площадку Babel и посмотреть, во что компилируется код ES2015 / ES6:


Транспортированный код из Вавилона

"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ExampleClass = exports.ExampleClass = function () {
    function ExampleClass() {
        _classCallCheck(this, ExampleClass);

        this.thisDoesntWork = function () {
            return 0;
        };
    }

    _createClass(ExampleClass, [{
        key: "thisWorks",
        value: function thisWorks() {
            return 0;
        }
    }]);

    return ExampleClass;
}();

Первое, что я заметил, это то, что стрелочные функции - это просто _instance методы_. Это означает несколько вещей:

  1. они не существуют до создания объекта.
  2. их нельзя заглушить, изменив прототип, так как они не существуют на прототипе
  3. их нельзя заглушить, изменив объект-конструктор, поскольку их определение скрыто внутри замыкания.

Зная все это, просто изменить свой неудачный тест на это:

    it("should stub thisDoesntWork arrow function", () => {
        var example = new ExampleClass();
        let stubFunctionB = sinon.stub(example, "thisDoesntWork", () => "actually it does work" );
    });

Удачи.

>Все замечания

Это пища для предстоящего нового сайта документации, где мы надеемся опубликовать еще несколько статей, ориентированных на обучение, по заглушкам, шпионажу и т. Д. В контексте ES2015.

Обычно, когда вы сталкиваетесь с подобными проблемами, очень полезно помнить один простой факт: ES2015 часто является просто синтаксическим сахаром поверх простых конструкций ES5. Это означает, что если вы не понимаете, почему что-то происходит (или не происходит), попробуйте деконструировать код до его эквивалента в ES5. Самый простой способ (это то, что я только что сделал) - просто вставить пример кода на площадку Babel и посмотреть, во что компилируется код ES2015 / ES6:


Транспортированный код из Вавилона

"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var ExampleClass = exports.ExampleClass = function () {
    function ExampleClass() {
        _classCallCheck(this, ExampleClass);

        this.thisDoesntWork = function () {
            return 0;
        };
    }

    _createClass(ExampleClass, [{
        key: "thisWorks",
        value: function thisWorks() {
            return 0;
        }
    }]);

    return ExampleClass;
}();

Первое, что я заметил, это то, что стрелочные функции - это просто _instance методы_. Это означает несколько вещей:

  1. они не существуют до создания объекта.
  2. их нельзя заглушить, изменив прототип, так как они не существуют на прототипе
  3. их нельзя заглушить, изменив объект-конструктор, поскольку их определение скрыто внутри замыкания.

Зная все это, просто изменить свой неудачный тест на это:

    it("should stub thisDoesntWork arrow function", () => {
        var example = new ExampleClass();
        let stubFunctionB = sinon.stub(example, "thisDoesntWork", () => "actually it does work" );
    });

Удачи.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги