thitzeman thitzeman - 3 months ago 49
TypeScript Question

Cannot stub arrow function in a class using Sinon


  • Sinon version : v2.0.0-pre.2

  • Environment : Windows 10

  • Other libraries you are using: Typescript, babel, mocha, chai



What did you expect to happen?

I expected to be able to stub an arrow function in a class.

What actually happens

I can't stub an arrow function, however, I can stub the class prototype function.

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)


How to reproduce

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");
});
});

Answer

I've never used sinon, but in their documentation it states for the sinon.stub function that it:

Replaces object.method with a stub function

If you look at the compiled js code of your ExampleClass:

var ExampleClass = (function () {
    function ExampleClass() {
        this.thisDoesntWork = function () {
            return 0;
        };
    }
    ExampleClass.prototype.thisWorks = function () {
        return 0;
    };
    return ExampleClass;
}());

Then you'll see that ExampleClass.prototype.thisWorks is defined, but there's no ExampleClass.thisDoesntWork definition, not even ExampleClass.prototype.thisDoesntWork.

The thisDoesntWork method is added only in the constructor (arrow functions aren't really class methods, they are just class members with a function type).

I suspect that this will work:

describe("ExampleClass tests", () => {
    it("should stub thisDoesntWork arrow function", () => {
        let stubFunctionB = sinon.stub(new ExampleClass(), "thisDoesntWork");
    });
});
Comments