【问题标题】:Node: Unable to mock aws-sdk methods节点:无法模拟 aws-sdk 方法
【发布时间】:2019-05-20 21:11:28
【问题描述】:

我已经尝试了很多我在互联网上找到的关于模拟 aws-sdk 服务的方法,但没有一个对我有用,我什至尝试了模块 aws-sdk-mock,但这不起作用,我认为这是因为我没有在函数处理程序中使用aws-sdk

我使用jest 作为我的测试运行器和断言,所以我现在的代码是这样的:

test.js

const aws = require('aws-sdk-mock');
const Admin = require('./../../../serverless/entities/Admin');

describe('Entity - Admin test', () => {
  jest.spyOn(aws.CognitoIdentityServiceProvider.prototype, 'listUsersInGroup', () => {
    return {
      promise: Promise.resolve({ foo: 'bar' })
    };
  });

  const data = Admin.getListOfUsers();

  console.log(data);
});

Admin.js

/**
 * Admin entity class
 * This class should help managing all super user actions that are required for the sportstracker's application
 * Amazon services used by this entity:
 *  - Cognito (User Pool)
 * Required IAM Policy actions:
 *  - cognito-idp:ListUsersInGroup
 *  - cognito-idp:ListUsers
 *  - cognito-idp:AdminCreateUser
 *  - cognito-idp:AdminDeleteUser
 *  - cognito-idp:AdminGetUser
 *  - cognito-idp:AdminListGroupsForUser
 *  - cognito-idp:AdminUpdateUserAttributes
 *  - cognito-idp:AdminRemoveUserFromGroup
 */

const aws = require('aws-sdk');
const User = require('./../lib/User');
const cognito = new aws.CognitoIdentityServiceProvider();
const UserPoolId = process.env['COGNITO_USER_POOL_ID'];

const rolesMap = {
  admin: 'SuperUser',
  member: 'Member'
};

/**
 * @typedef UsersList
 * @property {Array<UserObject>} members - The list of members
 * @property {Array<UserObject>} admins - The list of admins
 */

class Admin {
  /**
   * Gets a list of users for both admin and members.
   * This executes 2 methods for aws.cognito [admin, member]
   * @returns {Promise<UsersList>} - The object containing the list of members and admins
   */
  static async getListOfUsers () {
    const operations = [
      cognito.listUsersInGroup({ UserPoolId, GroupName: rolesMap.admin }).promise(),
      cognito.listUsersInGroup({ UserPoolId, GroupName: rolesMap.member }).promise()
    ];

    const results = await Promise.all(operations);

    return {
      admins: results[0].Users.map(user => User.mapUserData(user)),
      members: results[1].Users.map(user => User.mapUserData(user))
    };
  }

  ...
}

module.exports = Admin;

我得到的这段代码的错误是:

TypeError: Cannot read property 'prototype' of undefined

这是因为 sdk 中所有服务的原型在调用构造函数之前都没有定义方法,我明白为什么他们创建了一个像 aws-sdk-mock 这样的模块,但即使那个模块也没有帮助我,所以我该怎么做在非函数 lambda 处理程序中模拟 aws 服务的正确方法?

【问题讨论】:

    标签: node.js amazon-web-services unit-testing jestjs aws-sdk


    【解决方案1】:

    要模拟jest 中的第三方包,您可以在node_modules 的同一级别中创建一个__mocks__ 目录,该目录将包含您的模拟函数。

    例如,

    .
    ├── README.md
    ├── __mocks__
        └── aws-sdk.js
    ├── jest.config.js
    ├── node_modules
    ├── package.json
    ├── src
    └── yarn.lock
    

    您的aws-sdk.js 模拟文件可以包含以下内容:

    module.exports.CognitoIdentityServiceProvider = jest.fn(() => ({
        listUsersInGroup: mockListUsersInGroup,
    }))
    
    const mockListUsersInGroup = jest.fn((params) => ({
        // You can replace the resolved value.
        promise: () => Promise.resolve({}),
    }))
    

    【讨论】:

    • 是否可以让模拟文件对不同的测试有不同的响应?
    • 是的,你可以。模拟函数可以返回任何你想要的。
    • 我试过你的方法,但它仍然不起作用,结果方法是在运行时从构造函数填充的,所以这意味着我必须使用实例而不是原型
    • @OscarReyes 你有我可以查看的最小回购吗?
    【解决方案2】:

    这个适合我

    const AWS = require('aws-sdk');
    jest.mock('aws-sdk');
        
    AWS.CognitoIdentityServiceProvider.prototype.listUsers = jest.fn().mockReturnValue({
          promise: jest.fn().mockResolvedValue({})
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-02
      • 2019-03-30
      • 2018-08-17
      • 1970-01-01
      • 1970-01-01
      • 2022-09-26
      • 2019-12-09
      • 1970-01-01
      相关资源
      最近更新 更多