I am writing unit tests for a NestJS/Express server that uses the express-session
package. It has an object with methods that might not always be defined. In my code I check for it to exist first, like this:
clearAllSessions(): Promise<string> {
return new Promise<string>((resolve, reject) => {
if (this.sessionStore.clear != null) {
this.sessionStore.clear();
resolve(`The sessions have been cleared!`);
} else {
reject(new Error(`Unable to clear sessions!`));
}
});
}
And I am writing a test like this (which uses a helper method to get errors, not relevant here)
it('should throw an error when session clear is not available to be called', async () => {
jest.spyOn(sessionStore, 'clear').mockImplementation(undefined)
const result = await getError(() => adminSvc.clearAllSessions());
expect(sessionStore.clear).not.toHaveBeenCalled();
expect(result).toEqual(new Error(`Unable to clear sessions!`));
});
The problem is that this.sessionStore.clear
will return a jest mock function and not just plain undefined
like my code would check for, so the test takes that first code branch which is not what I want. How to I just mock the implementation to be nothing?
Just use Object.defineProperty()
to modifiy an existing property on an object.
const sessionStore: { clear?: () => void } = {
clear() {
console.log('real implementation');
},
};
describe('78741514', () => {
test('should pass', () => {
const restore = sessionStore.clear;
Object.defineProperty(sessionStore, 'clear', { value: undefined });
expect(sessionStore.clear).toBeUndefined();
sessionStore.clear = restore;
});
});