Reputation: 63
I am trying to mock a function of a singleton class fetching a value from the aws ssm parameter store.
The type definitions for getParameter() are as follows:
getParameter(params: SSM.Types.GetParameterRequest, callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void): Request<SSM.Types.GetParameterResult, AWSError>;
getParameter(callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void): Request<SSM.Types.GetParameterResult, AWSError>;
My test looks like this:
import {SSM} from 'aws-sdk';
import {SSMParameter} from './src/module/ssm/ssm-cache-parameter';
import {mocked} from 'jest-mock';
import { AWSError } from 'aws-sdk';
jest.mock('aws-sdk', () => {
const mSSMInstance = {
getParameter: jest.fn(),
};
const mSSM = jest.fn(() => mSSMInstance);
return { SSM: mSSM };
});
describe('amazon service mock', () => {
let ssmParameter: SSMParameter;
it('should get Parameter from Parameter Store', async () => {
ssmParameter = SSMParameter.getInstance();
expect(SSM).toBeCalled();
console.log(ssmParameter);
const mSSMInstance = new SSM();
const mData = {
Parameter: {
ARN: 'arn:aws:ssm:eu-test-1:123:NAME',
LastModifiedDate: new Date(2020, 09, 1),
Name: 'NAME',
Type: 'String',
Value: 'VALUE',
Version: 1,
}
};
const error: AWSError = {
code: 'ERROR_CODE',
message: 'ERROR_MESSAGE',
name: 'ERROR_NAME',
time: new Date(2020, 09, 1),
}
mocked(mSSMInstance.getParameter).mockImplementationOnce(
(params: SSM.GetParameterRequest, callback?: (err: AWSError, data: SSM.GetParameterResult) => void): any => {
if (callback) {
callback(error, mData);
}
},
);
const actual = ssmParameter.cache({Name: 'NAME', WithDecryption: false}, 30000);
expect(actual).toBe('VALUE');
});
});
I am getting the following error, which I believe is because TypeSCript doesn't know for certain which definition to use:
Argument of type '(params: SSM.GetParameterRequest, callback?: ((err: AWSError, data: SSM.GetParameterResult) => void) | undefined) => any' is not assignable to parameter of type '{ (params: GetParameterRequest, callback?: ((err: AWSError, data: GetParameterResult) => void) | undefined): Request<GetParameterResult, AWSError>; (callback?: ((err: AWSError, data: GetParameterResult) => void) | undefined): Request<...>; }'. Types of parameters 'params' and 'callback' are incompatible. Type '((err: AWSError, data: GetParameterResult) => void) | undefined' is not assignable to type 'GetParameterRequest'. Type 'undefined' is not assignable to type 'GetParameterRequest'.
I am stuck. Any help on how to resolve this would be much appreciated.
Upvotes: 0
Views: 902
Reputation: 63
The solution was to cast the signature I wanted to use for my test. I solved it as follows:
import {SSM, AWSError, Request} from 'aws-sdk';
import {cache} from './src/module/ssm/ssm-cache-parameter-wrapper';
jest.mock('aws-sdk', () => {
const mRequestInstance = {
promise: jest.fn(),
};
const mRequest = jest.fn(() => mRequestInstance);
const mSSMInstance = {
getParameter: jest.fn(() => Request),
};
const mSSM = jest.fn(() => mSSMInstance);
return {Request: mRequest, SSM: mSSM};
});
type GetParameter = (
params: SSM.Types.GetParameterRequest,
callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void
) => any;
describe('AWS System Manager Cache Mock', () => {
it('should get Parameter from Parameter Store', async () => {
const mSSMInstance = new SSM();
const mRequestInstance = new Request(mSSMInstance, 'getParameter', {Name: 'NAME', WithDecryption: false});
jest
.mocked(mSSMInstance.getParameter as GetParameter)
.mockImplementationOnce(
(
_params: SSM.Types.GetParameterRequest,
_callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void
) => mRequestInstance
);
jest.mocked(mRequestInstance.promise as any).mockResolvedValueOnce({
Parameter: {
Value: 'VALUE',
},
});
const actual = await cache({
cacheTimeInMilliSeconds: 30000,
decrypt: false,
name: 'NAME',
});
expect(SSM).toBeCalled();
expect(Request).toBeCalled();
expect(actual).toBe('VALUE');
});
});
Upvotes: 0