dwyl / aws-sdk-mock

:rainbow: AWSomocks for Javascript/Node.js aws-sdk tested, documented & maintained. Contributions welcome!
Apache License 2.0
1.09k stars 107 forks source link

v6.0.1 broken with `TypeError: AWS.mock is not a function` #411

Closed aannoune closed 4 weeks ago

aannoune commented 1 month ago

Hello Team, i updated aws-sdk-mock to v6.0.1 but when I'm trying to use it i have a TypeError: AWS.mock is not a function errors throwed.

my implementation is simple (plain javascript) and straight forward:

const AWS = require('aws-sdk-mock')

AWS.mock('DynamoDB.DocumentClient', 'batchWrite', (params, callback) => {
    mockBatchWrite(params)
    callback(null, true)
})

Any one could help ?

LuchoTurtle commented 1 month ago

@aannoune thank you for opening the issue. Since it was a major overhaul of the package from Javascript to Typescript, some of these issues were bound to occur. Thank you so much for letting us know!

I'll take a look at it and try to reproduce it.

nelsonic commented 1 month ago

Hi @aannoune thank you drawing our attention to this. 👌 while @LuchoTurtle is investigating, could you please help us isolate the issue by adding more detail to the OP: 🙏

Please confirm your code is working in < v6; does it still work if you manually downgrade and pin the version of aws-sdk-mock to 5.9.0. e.g: "aws-sdk-mock": "<=5.9.0", As per: https://stackoverflow.com/a/25861938/1148249

Thanks.

aannoune commented 1 month ago

hi @nelsonic : Of course : Node: v20.11.0 OS: Ubuntu 20.04 over win 10 wsl Testing with jest 29.7.0 I do confirm that the code works perfectly with v5.9.0 or below (i did had a first issue with v6.0.0). Exact syntaxe used : "aws-sdk-mock": "^5.9.0",

LuchoTurtle commented 1 month ago

Thanks for the feedback @aannoune !

I'm taking a look and trying to reproduce the errors with npm link locally on a newly Typescript project. I see the TypeError as well, which is mighty weird since the bundled files in dist clearly export the AWS object as default.

`index.js

module.exports = AWS;

index.d.ts

export { AWS as default };

The closest I've found was https://stackoverflow.com/questions/72142661/module-does-not-provide-an-export-named-default-compiled-typescript-module/

I'll see if I can get to the bottom of this and compare with the versions before v6. Thanks again for opening the issue, I really appreciate it!

LuchoTurtle commented 1 month ago

@aannoune I'm trying to reproduce your error. I've created a sandbox using the package and everything seems to work fine. (ignore the sinon errors in the console, what matters is that AWSMock is defined and you can call the functions). Check the image below to see it for yourself and to open the console.

https://codesandbox.io/p/sandbox/testing-zl3nqn

image

If you could provide us with a reproducible example or give us a rough outline of the commands you did and how you're running your project and the files, I'll be more than happy to try to get to the bottom of this.

LuchoTurtle commented 1 month ago

I think I may have found a resolution and drop "type": "module" from the package.json to support older js projects that use CommonJS.

I will still bundle with tsup to support both esm and cjs for anyone that wishes to import the package as an ESModule, but there's no benefit to having this setting turned on in package.json for now, as it's a source of headache.

https://github.com/m-radzikowski/aws-sdk-client-mock seems to have gone this route, as well.

@aannoune dismiss my previous comment, I'll open a PR shortly to address this issue.

LuchoTurtle commented 1 month ago

@aannoune v6.0.2 is published. Please do tell us if it's properly working now 😄

aannoune commented 4 weeks ago

Hello @LuchoTurtle , unfortunatly it does not fix the problem .. :-( i still got a " TypeError: AWS.mock is not a function" I tested in 2 different projects where we are using it and we have the same issue on both.

nelsonic commented 4 weeks ago

Strange. But thanks for the feedback. Could you please confirm one more thing: what version of the aws-sdk are you using?

aannoune commented 4 weeks ago

Here the info : ,"aws-sdk": "^2.1576.0",

nelsonic commented 4 weeks ago

@LuchoTurtle looks like we might need to spin up a Ubuntu machine to attempt to replicate this. 🐧 You can do this either natively on a Lenovo box @home 🖥️ or as a VM (e.g. Docker or VirtualBox on your Mac). 💻 I don't expect there to be a major diff between the native and VM. 💭

LuchoTurtle commented 4 weeks ago

@aannoune thank you for the feedback. Without a reproducible example where we can test ourselves, pinpointing your problem can be hard.

Here are my specs: OS: Mac Node and npm version: v20.9.0 and 10.5.1. Package versions:

"aws-sdk": "^2.1633.0",
"aws-sdk-mock": "^6.0.2",

I've created a simple project to run a small test to confirm the functions are correctly defined.

index.ts

import AWSMock from "aws-sdk-mock";
import AWS from "aws-sdk";
import { GetItemInput } from "aws-sdk/clients/dynamodb.js";

(async () => {

    // TEST1
    AWSMock.setSDKInstance(AWS);
    AWSMock.mock(
      "DynamoDB",
      "getItem",
      (params: GetItemInput, callback: Function) => {
        console.log("DynamoDB", "getItem", "mock called");
        callback(null, { pk: "foo", sk: "bar" });
      }
    );

    const input: GetItemInput = { TableName: "", Key: {} };
    const dynamodb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
    const returnPromise: any = await dynamodb.getItem(input).promise();
    if (returnPromise.sk !== "bar" || returnPromise.pk !== "foo") {
      throw new Error("Error");
    }    
    AWSMock.restore("DynamoDB");
  })();

package.json

{
  "name": "test",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@types/chai": "^4.3.16",
    "typescript": "^5.4.5"
  },
  "dependencies": {
    "aws-sdk": "^2.1633.0",
    "aws-sdk-mock": "^6.0.2",
    "expectations": "^1.0.0",
    "mocha": "^10.4.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2022",                                 
    "module": "NodeNext",                               
    "esModuleInterop": true,                            
    "forceConsistentCasingInFileNames": true,           
    "strict": true,                                     
  }
}

With only these three files, I simply run the following commands:

npm install
tsc
node index.js

These will install the dependencies, tsc will transpile the ts file into a js file and node index.js will run it. You'll see that it runs fine, without any TypeError errors.

I don't know how you are trying to run your project, can you provide an example or steps so we can try to reproduce your exact project/problem?

aannoune commented 4 weeks ago

@LuchoTurtle : i creted a small repo with a minimalistic project that implement my approche and that reproduce the bug https://github.com/aannoune/aws-sdk-mock-issue411

aannoune commented 4 weeks ago

`> mocktest@1.0.0 test

NODE_ENV=test SUPPRESS_NO_CONFIG_WARNING=1 LOG_LEVEL=fatal jest --verbose --coverage --reporters=default --reporters=jest-junit

FAIL tests/mock.test.js simple test ✕ dynamo call

● simple test › dynamo call

TypeError: AWS.mock is not a function

   5 | describe('simple test', ()=>{
   6 |     beforeAll( ()=>{
>  7 |              AWS.mock('DynamoDB.DocumentClient', 'query', (params, callback) => {
     |                  ^
   8 |                      callback(null, {
   9 |                              Items: [{fakeResponse:true}]
  10 |

  at Object.mock (tests/mock.test.js:7:7)
---------- --------- ---------- --------- --------- ------------------- File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 33.33 100 0 33.33
index.js 33.33 100 0 33.33 5-9
---------- --------- ---------- --------- --------- -------------------

Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 0.743 s, estimated 1 s Ran all test suites.`

aannoune commented 4 weeks ago

@LuchoTurtle I provided a branch with version 5.9.0 that works : ` npm run test

mocktest@1.0.0 test NODE_ENV=test SUPPRESS_NO_CONFIG_WARNING=1 LOG_LEVEL=fatal jest --verbose --coverage --reporters=default --reporters=jest-junit

console.log [ { fakeResponse: true } ]

  at Object.log (tests/mock.test.js:17:12)

PASS tests/mock.test.js simple test ✓ dynamo call (24 ms)

---------- --------- ---------- --------- --------- ------------------- File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 100 100 100 100
index.js 100 100 100 100
---------- --------- ---------- --------- --------- -------------------

Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 0.535 s, estimated 1 s`

LuchoTurtle commented 4 weeks ago

@aannoune thank you so much for the reproducible example, you're the man!

I think I've narrowed down where the issue is. The way the Typescript is being transpiled outputs the default export erroneously. I'll work on getting this fixed.

In the meantime, if you want to use the latest version and still have it working, you can use AWS.default.mock instead of AWS.mock. It will work that way (at least while I work on the issue).

LuchoTurtle commented 4 weeks ago

@aannoune 6.0.3 has been published and it should work. Let us know if it doesn't (just tested with your example and it seems to be working properly now).

Thanks!

aannoune commented 4 weeks ago

@LuchoTurtle : it work 👍 Thanks a lot for your responsiveness