Skip to content

testing/mock.ts: Add support for stubbing properties #5848

@KyleJune

Description

@KyleJune

Is your feature request related to a problem? Please describe.

Currently the mocking tool doesn't support stubbing getter/setter properties. It only allows stubbing functions. Other mocking tools like sinon do support it.

It's probably not a common need and would just be a nice to have. I'm creating this issue based on a comment someone made in the discord's #dev-std channel where they were requesting a way to stub a getter.

Describe the solution you'd like

The ideal solution to this problem to me would be to add an additional call signature to the stub function, that allows you to pass a property descriptor instead of a function as the third argument.

stub<Self, Prop extends keyof Self>(self: Self, property: Prop, descriptor: Omit<PropertyDescriptor, 'configurable'>)

It would need to omit the configurable property since a property must be configurable for it to be able to be restored to it's original value.

If a get or set function are set on the descriptor, they should be wrapped in a spy so that you can make assertions about them being called. You would just need a way to access them. Maybe the value returned by the stub function could have get and set properties on it so that people can access the spys by doing myStub.get or myStub.set where myStub is the value returned by the stub function when you call it with a property descriptor instead of a function.

For more information about property descriptors, see Object.defineProperty documentation on mdn.

Describe alternatives you've considered

With sinon.js, you can mock properties by creating a stub then calling the get, set, or value functions on the stub object. That can be seen at the end of the following page. I'm guessing it's at the end because it's uncommon to use it, but it would be good to have for when people want to do this.

https://sinonjs.org/releases/latest/stubs/

Here is an example of stubbing a getter with sinon.

const sinon = require("sinon");
const referee = require("@sinonjs/referee");
const assert = referee.assert;

describe("stub", function () {
    it("should replace getter", function () {
        const myObj = {
            prop: "foo",
        };

        sinon.stub(myObj, "prop").get(function getterFn() {
            return "bar";
        });

        assert.equals(myObj.prop, "bar");
    });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    PR welcomeA pull request for this issue would be welcomeenhancementNew feature or requesttesting

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions