Mock a dependency's constructor Jest
Above answer works. However, after some time working with jest I would just use the mockImplementation functionality which is useful for mocking constructors.
Below code could be an example:
import * as AWS from 'aws-sdk';
jest.mock('aws-sdk', ()=> {
return {
CloudWatch : jest.fn().mockImplementation(() => { return {} })
}
});
test('AWS.CloudWatch is called', () => {
new AWS.CloudWatch();
expect(AWS.CloudWatch).toHaveBeenCalledTimes(1);
});
Note that in the example the new CloudWatch() just returns an empty object.
The problem is how a module is being mocked. As the reference states,
Mocks a module with an auto-mocked version when it is being required. <...> Returns the jest object for chaining.
AWS
is not module object but jest
object, and assigning AWS.CloudFormation
will affect nothing.
Also, it's CloudWatch
in one place and CloudFormation
in another.
Testing framework doesn't require to reinvent mock functions, they are already there. It should be something like:
const AWS = require("aws-sdk");
const fakePutMetricData = jest.fn()
const FakeCloudWatch = jest.fn(() => ({
putMetricData: fakePutMetricData
}));
AWS.CloudWatch = FakeCloudWatch;
And asserted like:
expect(fakePutMetricData).toHaveBeenCalledTimes(1);
According to the documentation mockImplementation
can also be used to mock class constructors:
// SomeClass.js
module.exports = class SomeClass {
method(a, b) {}
};
// OtherModule.test.js
jest.mock('./SomeClass'); // this happens automatically with automocking
const SomeClass = require('./SomeClass');
const mockMethod= jest.fn();
SomeClass.mockImplementation(() => {
return {
method: mockMethod,
};
});
const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method: ', mockMethod.mock.calls);
If your class constructor has parameters, you could pass jest.fn()
as an argument.