如何使用单例类解决AWS模拟测试

时间:2019-06-25 08:50:28

标签: amazon-web-services ecmascript-6 jestjs

当我通过npm通过AWS模拟在Javascript测试中执行Jest时,将是失败。 因为我使用单例课程。

像这里的区别。

“ module.exports = Users;”或“ module.exports = new Users();”

我想AWS模拟不适用于单例类。

在那个原因下,我应该怎么解决这个问题?

'use strick';

var aws = require('aws-sdk')
aws.config.update({region:'ap-northeast-1'})

class Users {

    constructor() {
        this.table = 'Users'
        this.dynamodb = new aws.DynamoDB()
    }

    getData(email) {
        let params = {
            TableName: this.table,
            Key      : { 'email': {'S':email} }
        }

        return this.dynamodb.getItem(params).promise()
    }
}
// module.exports = Users // ← this will be success.
module.exports = new Users(); // ← this will be failure.
'use strict';

var aws = require('aws-sdk-mock'),
    users = require('./user'),
    chai = require('chai'),
    path = require('path'),
    should = chai.should(),
    input = 'test@gmail.com',
    usersObj;

aws.setSDK(path.resolve('node_modules/aws-sdk'));

describe('All Tests', function () {
    // this.timeout(0);
    beforeEach(function () {
        aws.mock('DynamoDB', 'getItem', function (params, callback) {
            callback(null, {Item: {email: params.Key.email.S}});
        });

        // usersObj = new users(); ← this will be success.
        usersObj = users; // ← this will be failure.
    });

    it('getData', function (done) {
        usersObj.getData(input).then(function (res) {

            console.log(res);

            res.Item.email.should.equal(input);
            done();
        });
    });
});

3 个答案:

答案 0 :(得分:0)

此行:

module.exports = new Users();

...表示在代码运行后将立即创建一个Users对象,并且在user.jsrequired时它将立即运行。

此行:

users = require('./user')

...位于测试文件的顶部和以下行:

aws.mock('DynamoDB', 'getItem', function (params, callback) {
  callback(null, {Item: {email: params.Key.email.S}});
});

...在beforeEach中...

...这意味着user.jsrequired,并在创建模拟之前运行...导致测试失败。


如果您要导出Users的实例,则只需要确保直到之后,才require测试中的user.js文件您已经设置了模拟:

var aws = require('aws-sdk-mock'),
  chai = require('chai'),
  path = require('path'),
  input = 'test@gmail.com',
  usersObj;
chai.should()

aws.setSDK(path.resolve('node_modules/aws-sdk'));

describe('All Tests', function () {
  beforeEach(function () {
    aws.mock('DynamoDB', 'getItem', function (params, callback) {
      callback(null, { Item: { email: params.Key.email.S } });
    });  // <= set up the mock first...

    usersObj = require('./user');  // <= ...then require user.js
  });

  it('getData', function (done) {
    usersObj.getData(input).then(function (res) {
      res.Item.email.should.equal(input);  // Success!
      done();
    });
  });
});

答案 1 :(得分:0)

我也可以解决这个问题。

'use strict';

var aws = require('aws-sdk-mock'),
    users = require('./user'),
    chai = require('chai'),
    path = require('path'),
    should = chai.should(),
    input = 'test@gmail.com',
    usersObj;

const awsObject = require('aws-sdk');

aws.setSDK(path.resolve('node_modules/aws-sdk'));

describe('All Tests', function () {
    // this.timeout(0);
    beforeEach(function () {
        aws.mock('DynamoDB', 'getItem', function (params, callback) {
            callback(null, {Item: {email: params.Key.email.S}});
        });

        // it will be resolve problem by creating new AWS instance.
        users.dynamodb = new awsObject.DynamoDB();
    });

    it('getData', function (done) {
        users.getData(input).then(function (res) {

            console.log(res);

            res.Item.email.should.equal(input);
            done();
        });
    });
});

答案 2 :(得分:0)

您必须在类构造函数内调用aws客户端

class MyClass {
  constructor(){
    this.dynamodb = new DynamoDB.DocumentClient({ region: "us-west-2" });
  }
...

在测试文件中,必须在调用de AWSMock之后立即创建类的新实例。示例:

it('Should save on dinamoDB with param atributes void()', async () => {
  AWSMock.mock('DynamoDB.DocumentClient', 'update', function (params, callback){
    callback(null, { Attributes: { currentValue: 1 } } );
  });
  AWSMock.mock('DynamoDB.DocumentClient', 'put', function (params, callback){
    callback(null, true);
  });

  const myClass = new MyClass();
...