3

So this question was asked and there was an answer here: Is it possible to use TypeScript with 'aws-sdk-mock'

I don't have enough reputation to ask about the answer, so I had to create another question, because I couldn't get the answer to work.

Here's the entirety of my test code:

const AWSMock = require('aws-sdk-mock');
const AWS = require('aws-sdk');
AWSMock.setSDKInstance(AWS);
AWSMock.mock('DynamoDB', 'putItem', function (params, callback) {
  console.log('MOCK WORKS!')
});

const ddb = new AWS.DynamoDB();
ddb.putItem(null, function(err, data) {
  console.log('NOT MOCKED!')
});

AWSMock.restore();

Versions:

aws-sdk: 2.286.2

aws-sdk-mock: 4.0.0

Test framework: mocha 3.4.2

Any thoughts? Thanks!

Ben
  • 61
  • 2
  • 4
  • 1
    What is not working with your code? – Matt McCutchen Aug 03 '18 at 19:10
  • It says 'NOT MOCKED!' instead of 'MOCK WORKS!' – Ben Aug 03 '18 at 19:39
  • Doesn't seem to have much to do with typescript. – Bijou Trouvaille Aug 03 '18 at 20:31
  • 1
    Other people are also having difficulty getting aws-sdk-mock working with Typescript: https://github.com/dwyl/aws-sdk-mock/issues/140 So someone suggested the line 'AWSMock.setSDKInstance(AWS);', but that doesn't work for me. – Ben Aug 03 '18 at 20:48
  • Maybe it still helps, here is my solution: https://stackoverflow.com/questions/56192920/mocking-aws-sdk-promises-with-aws-sdk-mock-using-jest/56229531#56229531 – wzr1337 May 21 '19 at 00:03

2 Answers2

3

I was having this same issue, and the solution ended up being simple: I was using the wrong AWS instance.

In the examples I saw, they all created a new AWS instance in the test file, but what worked for me was using the same AWS instance from my source code that I wanted to test.

source.ts

export const aws = require('aws-sdk')

export async function myFunction(bucket: string): Promise<string> {
    const params: any = { Bucket: bucket }
    const s3 = new aws.S3()

    s3.listObjects(params, (err: any, data: any) => {
        // ...
    })
}

source.test.ts

import * as AWSMock from "aws-sdk-mock"
import {aws, myFunction} from "source.ts"

describe("myFunction", () => {
    it("should be mocked", async () => {
        AWSMock.setSDKInstance(aws)
        AWSMock.mock('S3', 'listObjects', (params: any, callback: Function) => {
            callback(null, {Contents: [{Key: 'file1.csv'}]})
        })

        // ... 
        AWSMock.restore()
    })   
})

Note that the type of params doesn't have to be the actual type from the aws-sdk type definitions. any worked for me.

Also, like the other answers have said, you need to initialize the AWS service inside the function that you're testing (source)

purpleladydragons
  • 1,305
  • 3
  • 12
  • 28
1

I came across the same problem with the same piece of code like you. I solved it. First, you are right you have to set the SDKInstance in typescript as it would seem. Second, the first parameter in the mocked function must be of type PutItemInput, which cannot be null. If you are mocking another function like GetItem the first Parameter must be of type GetItemInput, and so on. Here is my working solution with GetItem:

mock('DynamoDB', 'getItem', function(params: GetItemInput, callback: Function) {
  console.log('mock called');
  callback();
}

let input: GetItemInput = { TableName: '', Key: {} };

const dynamodb = new DynamoDB({apiVersion: '2012-08-10'});
dynamodb.getItem(input, () => {
  console.log('cb called');
});

If I omit the params in the getItem call it is also not working.

What you have to do to make this work with PutItem-Method is to replace GetItemInput with PutItemInput.

evayly
  • 832
  • 7
  • 18