Reputation: 6622
I have a function that looks like this:
function connect() {
const secret = 'secret';
const key = 'key';
const region = 'region';
const client = new AWS.DynamoDB({
secret,
key,
region
});'
return new AWS.DynamoDB.DocumentClient({ service: client })
}
I would like to test the function connect. I have mocked the DynamoDB constructor like this:
// See https://stackoverflow.com/questions/47606545/mock-a-dependencys-constructor-jest
jest.mock('aws-sdk', () => {
const DynamoDB = jest.fn().mockImplementation(() => {
return {};
});
return {
DynamoDB,
};
});
However, this means that the DocumentClient
constructor fails. How do I mock that as well?
Upvotes: 9
Views: 25050
Reputation: 967
Trying out the most voted answer, I tried to mock the document client and it didn't work.
I got this error: TypeError: AWS.DynamoDB.DocumentClient is not a constructor
Instead, I realized that I had to mock the DocumentClient as a class, not a function.
So, with that in mind, this is what worked instead:
jest.mock(`aws-sdk`, () => {
class mockDocumentClient {
async put(config) {
//TODO: your logic here
return true;
}
async query(config) {
// TODO: your logic here
return true;
}
}
return {
DynamoDB: {
DocumentClient: mockDocumentClient,
}};
});
Upvotes: 2
Reputation: 1
For me, what worked is the following:
import AWS from "aws-sdk"
...
jest.spyOn(AWS.DynamoDB, "DocumentClient").mockReturnValue(mockedDocumentClient);
Here mockedDocumentClient is my mock object that fakes the DocumentClient behaviour. I just include the methods I would use on it.
Upvotes: 0
Reputation: 692
Jest provides DynamoDB integration for running tests. See this document, look at 3. Configure DynamoDB client
:
const {DocumentClient} = require('aws-sdk/clients/dynamodb');
const isTest = process.env.JEST_WORKER_ID;
const config = {
convertEmptyValues: true,
...(isTest && {endpoint: 'localhost:8000', sslEnabled: false, region: 'local-env'})
};
const ddb = new DocumentClient(config);
I guess you can abstract out (if you haven't already) the DynamoDB client configuration into its own module file and export that client so that it can be required elsewhere, and when the Jest tests run, the client gets configured to point the mock DynamoDB server/tables that you have set up as per the other steps of the Jest DynamoDB documentation.
Upvotes: 0
Reputation: 292
Building on the comment from duxtinto above:
In my case (and in the case of the OP if I'm reading it right), DynamoDB isn't being called as a function, but rather is an object with a DocumentClient field on it, so this worked for me:
jest.mock('aws-sdk', () => {
return {
DynamoDB: { // just an object, not a function
DocumentClient: jest.fn(() => ({
put: mockDynamoDbPut
}))
}
}});
Upvotes: 10
Reputation: 69
Here what worked for me using jest with TypeScript:
// blabla.test.ts
import { DynamoDB } from 'aws-sdk';
import { ConsumerClass } from '../consumer-class';
import { DependencyConsumerClass } from '../dependency-consumer-class';
/*
* Inside consumerClassInstance.save() is calling this.dynamo.putItem({...}).promise();
*/
jest.mock('aws-sdk', () => {
return {
DynamoDB: jest.fn(() => {
return {
putItem: jest.fn(() => {
return {
promise: jest.fn(() => true)
};
})
};
})
};
});
test('sample test', async () => {
const dependencyConsumerClass = new DependencyConsumerClass();
const consumerClassInstance = new ConsumerClass(dependencyConsumerClass, new DynamoDB());
const result = await consumerClassInstance.save();
console.log(result);
});
Upvotes: 1
Reputation: 489
This worked for me:
const mockDynamoDbPut = jest.fn().mockImplementation(() => {
return {
promise() {
return Promise.resolve({});
}
};
});
jest.doMock('aws-sdk', () => {
return {
DynamoDB: jest.fn(() => ({
DocumentClient: jest.fn(() => ({
put: mockDynamoDbPut
}))
}))
};
});
I hope it's helpful for you too.
Regards,
David.
Upvotes: 7
Reputation: 1081
DocumentClient
might call some of the client
method, so simply define those methods stub. Say for example, DocumentClient
would use batchGetItem
, in your code
import AWS from 'aws-sdk';
jest.mock('aws-sdk', () => {
const DynamoDB = jest.fn().mockImplementation(() => {
return {
batchGetItem: jest.fn(),
};
});
return {
DynamoDB,
};
});
// you could inspect the mock
console.log(new AWS.DynamoDB({ ... }));
Upvotes: 5