I am using Jest to perform unit tests on a Node.js app, where the code source is written in TypeScript and then compiled into JavaScript.
In one of the classes that I wish to test, an external module is imported and a method from this module is used. I want to mock the calls to this method, in order to test only my code.
However, when I run the test, I get the following error:
TypeError: Cannot redefine property: methodName
The problem is that this method has the following Object Properties:
{ value: [Function],
writable: false,
enumerable: true,
configurable: false }
The configurable: false
is what makes it a big problem. I cannot redefine the properties before my mock call to make it writable.
Here is what the relevant code looks like:
Tested Class
import externalType from 'external-module-name';
export class ClassName {
public propertyName: externalType;
public method(param: string): Promise<any> {
return new Promise((resolve, reject) => {
this.propertyName.externalMethod(param)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
}
Unit Test
import { ClassName } from 'path/to/class';
describe('class', () => {
const class = new ClassName;
it("Blahblah", (done) => {
Object.defineProperty(class['propertyName'], 'externalMethod', {writable: true});
const spy = jest.spyOn(class['propertyName'], 'externalMethod').mockReturnValue(Promise.resolve());
class.method('string')
.then((result) => {
// Various expect()
done();
});
});
});
What I tried so far
I added the following line in my test:
Object.defineProperty(class['module'], 'methodName', {writable: true});
I defined my mock call as following:
jest.spyOn(class['module'], 'methodName').mockReturnValue(Promise.resolve());
I defined my mock call as following:
class.propertyName.externalMethod = jest.fn().mockImplementation((query) => { return Promise.resolve(); });
I tried to override the property that I'm calling, as following:
class.propertyName = <any> { externalMethod = (param: any) => { return Promise.resolve(); } }
For this one I get the error TypeError: Cannot assign to read only property externalMethod of object class
, which makes sense since readable is set to false.
But everything seems blocked from the attribute configurable
. I'm sure there is something that can be done because I am probably not the only one who wants to perform unit tests on a class that imports an external module, as secure as it is.
So my question is: what would be a clean and working way of mocking the external method? And if it is strictly impossible, what would be a way of testing my class without calling that external method?
Thanks in advance!