Skip to content

Allow to reset the value of MockFunctionContext.#calls #45795

Closed
@GauBen

Description

@GauBen

What is the problem this feature will solve?

I use globally mocked objects in my tests to allow them to run without an environment:

// Something that looks like a nodemailer object
export const mailer = {
  sendMail: mock.fn(() => Promise.resolve())
};

Because it's global, tests can pollute each other:

it('works', () => {
  mailer.sendMail({ to: "[email protected]" });
  assert.equal(mailer.sendMail.mock.callCount(), 1);
});

it('also works', () => {
  mailer.sendMail({ to: "[email protected]" });
  assert.equal(mailer.sendMail.mock.callCount(), 1); // It fails here, `callCount()` is now 2
});

What is the feature you are proposing to solve the problem?

I want to be able to reset mailer.sendMail.mock.calls:

describe('something', () => {
  beforeEach(() => {
    mailer.sendMail.mock.reset(); // Method name open to bikeshedding
  })
})

get calls() {
return ArrayPrototypeSlice(this.#calls, 0);
}
callCount() {
return this.#calls.length;
}

It could be as simple as:

reset() {
  this.#calls = [];
}

If you're okay with this design, I'm interested in creating a PR with the feature and associated tests.

What alternatives have you considered?

Use another mocking library

Current workaround

I resorted to this hack:

let prevCount = 0;
mailer.sendMail.mock.constructor.prototype.lastCalls = function () {
  const count = this.callCount();
  const tail = this.calls.slice(prevCount);
  prevCount = count;
  return tail;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues that request new features to be added to Node.js.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions