Unit Tests in Serverless

I seem to be having some trouble running the unit tests. When running npm test I get the following error.

  SyntaxError: Cannot use import statement outside a module

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)

This is running node 12.11.1 on Windows 10. Package.json is as follows:

{
  "name": "notes-app-api",
  "version": "1.1.0",
  "description": "A Node.js starter for the Serverless Framework with async/await and unit test support",
  "main": "handler.js",
  "scripts": {
"test": "jest"
  },
  "author": "",
  "license": "MIT",
  "repository": {
"type": "git",
"url": "https://github.com/AnomalyInnovations/serverless-nodejs-starter.git"
  },
  "devDependencies": {
"aws-sdk": "^2.545.0",
"jest": "^24.9.0",
"serverless-bundle": "^1.2.5",
"serverless-dotenv-plugin": "^2.1.1",
"serverless-offline": "^5.3.3"
  },
  "dependencies": {
"stripe": "^7.10.0",
"uuid": "^3.3.3"
  }
}

Any ideas?

I’m also hitting problems when I try to deploy using Seed. Logged error is

```
    /tmp/seed/source/tests/billing.test.js:1
```

```
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { calculateCost } from "../libs/billing-lib";
```

```
                                                                                                    ^
```

```

```

```
    SyntaxError: Unexpected token {
```

```

```

```
      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
```

```
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
```

and

```
ERROR: FAIL tests/billing.test.js
```

```
ERROR:   ● Test suite failed to run
```

```
ERROR: 
```

```
ERROR:     Jest encountered an unexpected token
```

```
ERROR: 
```

```
ERROR:     This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
```

```
ERROR: 
```

```
ERROR:     By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
```

```
ERROR: 
```

```
ERROR:     Here's what you can do:
```

```
ERROR:      • To have some of your "node_modules"
```

Hmm you might be using an older version of the tutorial. The test command should be using serverless-bundle test instead.

1 Like

That seems to have done the trick. I was halfway through the tutorial when you released the node 8 > 10 update. Started again from scratch but it must have cached something somewhere.

Thanks for the help and thank you for creating such a great tutorial series.

1 Like

Glad you figured it out!

This worked for me, great idea!

1 Like

Hmm that page doesn’t have the line you are talking about?

I know this is an old thread, but you’ve been super helpful in the past and I can’t seem to find any information on what I’m trying to do with unit testing. My question is, “How do I unit test a serverless lambda function with DB calls when there’s no connection to the DB before it’s been deployed?”. Example:

export async function getResources(){
    const resources = await db('resources')
    .select('resources.firstname, 'resources.lastname');

    //do something with the object returned

return resources;
}

In this case, I’d like to test what I’m doing with the returned object(which would be where the comment is), but need to somehow get the test to skip the db call and replace it with mock data we’ve created and check the result. Any tips would be greatly appreciated. Thanks!

I’ve only used Python for this stuff before so I’m new to the Javscript AWS world. But a little bit of looking around and maybe this article can help: it mocks out the AWS SDK for JavaScript

I still had problems with that error today. I dug around and learnt a little about ECMAScript modules. If you create another package.json inside test/ and say it’s a module, it works for me:

tests/package.json

{
  "type": "module"
}

Output:

(serverless-stack) bash-3.2$ npm test

> notes-app-api@1.1.0 test /Users/julian/learn/serverless-stack/notes-app-api
> serverless-bundle test

 PASS  tests/billing.test.js
  ✓ Lowest tier (3ms)
  ✓ Middle tier
  ✓ Highest tier (1ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        1.636s, estimated 2s
Ran all test suites.
1 Like

Great tutorial, thank you!

Any idea how I could use jest or any other testing library to test one API Gateway endpoint protected by Cognito?

As an extra level of security, I’m using CognIto Identity Id as param to post data in DynamoDB and so to prevent a malicious user with access in the same pool to post data on behalf of an other user, but I could not really figure out how to test it.

Here an example of DynamoDb param I’m using to update user data:

const params = {
    TableName: "products",
    Key: {
      userId: event.requestContext.identity.cognitoIdentityId,
      productId: event.pathParameters.productId
    },

Typically we end up testing the Lambda function directly as unit tests. But maybe you are looking for integration testing?

Hi Jayar,
Correct, I’m trying to implement a proper integration testing.

Yeah we haven’t covered it here. That might be something we look at in the future.

Thank you Jayair,
That’s pitty, as this tutorial is seriously the best one I could see anywhere on innternet and integration testing is an important task to accomplish in software development workflow.
On intenet I could not find any solution I liked when it comes to integration/acceptance testing using serverless without breaking the CI/CD workflow, so I ended up defining a pattern myself.
I dunno if it is the best way to do it but it is working well for my use case where I had other services to integrate and test on top of dynamoDB (ie. appsync graphql endpoints).

Basically, I used aws sdk to remotely login a test user and then get the deployed endpoints to be tested from a lambda which gets them from a cloudFormation stack output i.e.:
APPSYNC_URL: ${cf:${self:service}-${opt:stage}.GraphQlApiUrl}
and returns it to the integration-test when invoked.

The solution gives me a very high degree of confidence that all services are working well together and doesn’t break the CI/CD workflow everytime an endpoint is changed or added to the service.

On Seed platform worked like a charm.

1 Like

Awesome! Yeah that makes sense. Thanks for sharing!

I also ran into the “SyntaxError: Cannot use import statement outside a module” error. CommonJS style imports did the trick.

I’m using a v4.0 pdf of the tutorial that has Jest as the test runner. Reading up on the comments below, it sounds like there might be a new version of the tutorial using plug-in to run tests.

Oh thanks for letting me know. Can you post a screenshot from the PDF that needs to be updated?

Hello I receive this error whith serverless test option and also jest option the same

      19 files checked.
  testMatch: /Users/ilanohayon/escrow/notes-app-api/**/__tests__/**/*.{js,jsx,ts,tsx}, /Users/ilanohayon/escrow/notes-app-api/**/*.{spec,test}.{js,jsx,ts,tsx} - 0 matches
  testPathIgnorePatterns: /node_modules/ - 19 matches
  testRegex:  - 0 matches
Pattern:  - 0 matches
npm ERR! Test failed.  See above for more details.

Do you have any tests in your project?