使用Jest对AWS Lambda进行单元测试

时间:2020-03-25 06:32:37

标签: node.js unit-testing aws-lambda jestjs

const invokeApi = require("/opt/nodejs/kiwiCall");
const decrypt = require("/opt/nodejs/encryption");
const cors = require("/opt/nodejs/cors");

当我通过手动模拟 mocks 目录中的依赖项来测试index.js文件时,如下所示:

__mocks__ 
    |_invokeApi
    |_decrypt
    |_cors

FAIL  ./index.test.js
  ● Test suite failed to run

    Cannot find module '/opt/nodejs/kiwiCall' from 'index.js'

    However, Jest was able to find:
        '../../../../lambdas/Flights/Locations/index.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

    See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

      1 | "use strict";
      2 | 
    > 3 | const invokeApi = require("/opt/nodejs/kiwiCall");

想知道如何在inedx.test.js文件中模拟AWS lambda的依赖关系

3 个答案:

答案 0 :(得分:1)

在package.json或jest.config中,您可以为该目录添加moduleNameMapper。

get

答案 1 :(得分:0)

我几乎有同样的问题。我定义了一个层,其中包含在我的项目中其他功能之间共享的通用代码。我的项目结构如下所示:

project/
  functions/
    function1/
      app.js
    function2/
      app.js
  shared/
    shared.js

我这样导入我的共享库:

const { doSomething } = require('/opt/shared');

exports.handler = async (event) => {
  const result = await doSomething();
  // etc...
  return {statusCode: 200};
}

当我部署到AWS Lambda时,此方法有效,因为/opt/shared存在并且可以正确引用。如果我使用sam local invoke Function1在我的机器上运行它,它也可以工作,因为它在容器中运行,这使得/opt/shared可用于代码。

但是,我正在努力研究如何在单元测试中模拟这种依赖关系。如果我只是这样做:jest.mock('/opt/shared'),我会得到:Cannot find module '/opt/shared' from app.test.js

答案 2 :(得分:0)

因此我设法根据自己的存储库找出了一些东西。

我正在使用moduleNameMapper将绝对路径映射到存储库中存储图层的另一个位置。

例如

moduleNameMapper: {'^/opt/config/config': '<rootDir>/src/layers/layers-core/config/config'}

在您的情况下,您可以使用正则表达式来匹配/opt/nodejs/并将其映射到其他位置。希望有帮助。

编辑:

我彻底改变了方法,并使用babel-plugin-module-resolver和babel-rewire。我这样做是因为上述方法与rewire不兼容。设置非常简单,您只需要在.babelrc内设置babel别名即可。

例如

{
  "plugins": [
    ["rewire"],
    ["babel-plugin-module-resolver", {
      "alias": {
        "/opt/config/config": "./src/layers/layers-core/config/config",
        "/opt/utils/util-logger": "./src/layers/layers-core/utils/util-logger",
        "/opt/slack": "./src/layers/layers-slack/slack"
      }
    }]
  ]
}

使用IDE jsconfig.json路径别名将其组合起来,您将获得完整的IDE支持。

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2018",
    "baseUrl": "./",
    "paths": {
      "/opt/config/config": ["src/layers/layers-core/config/config"],
      "/opt/utils/util-logger": ["src/layers/layers-core/utils/util-logger"],
      "/opt/slack/*": ["src/layers/layers-slack/slack/*"],
    }
  },
  "exclude": ["node_modules", "dist"]
}

然后您可以使用jest.doMock('/opt/config/config', mockConfig);

引用图层

编辑2: 找到了一种方法来使Jest模拟它。只需将{virtual: true}放入模拟游戏中即可!

jest.doMock('/opt/config/config', mockConfig, {virtual: true});