I'm currently writing unit tests for a piece of software, and bumped into a problem that had me stumped for two days. I have services done with dependency injection pattern, which I can mock those just fine, until I got to the services that had DynamoDB.DocumentClient dependencies.
I have tried the following, using this fictitious service as example: cats.service.ts
import { DynamoDB } from 'aws-sdk';
import { Repository } from 'typeorm';
import { CatDTO, CatEntity} from 'somewhere';
export class CatsService {
constructor(
private readonly catRepository: Repository<CatEntity>,
private readonly clientDB: DynamoDB.DocumentClient,
){}
async findCat (name: string): Promise<CatDTO> {
try{
const result = await this.clientDB.query(name).promise();
return result
} catch(error){
throw new Error(error)
}
The problem: I can mock the repositories, but not the AWS SDK DynamoDB.DocumentClient.
I have tried lots of stuff, such as jest's manual mocking of the module, jest.mock
ing directly on the code as described here, here, here and also here.
The thing is: I tried going for something similar that I do with the typeorm repositories, that is:
const mockCatRepository = {
findOne: jest.fn(),
} as unknown as Repository<CatEntity>;
// Here I tried mocking the clientDB DocumentClient in all the ways linked above, such as:
jest.mock('aws-sdk', () => {
return {
DynamoDB: {
DocumentClient: jest.fn(),
},
};
});
describe('CatsService typeorm repository dependency example', () => {
let service: CatsService;
let mockClientDB: DynamoDB.DocumentClient;
beforeEach(() => {
mockClientDB = {} as DynamoDB.DocumentClient;
mockClientDB.query = jest.fn().mockReturnValue({ promise: jest.fn() });
service = new CatsService(
mockCatRepository,
mockClientDB,
);
});
it('should return a cat successfully', async () => {
const mockInput='Peanut';
// and nothing I tried above I could manage to do something like:
const mockDynamoReturn = { Items: [{ name: 'Peanut', breed: 'Tabby' }] };
clientDB.query.promise.mockResolvedValueOnce(mockDynamoReturn)
// since either query or promise don't actually get mocked.
// in this specific case, the following error:
error TS2339: Property 'mockResolvedValue' does not exist on type '() => Promise<PromiseResult<QueryOutput, AWSError>>'
Thanks for your time reading this!