【问题标题】:Mocking dynamodb scan using jest使用 jest 模拟 dynamodb 扫描
【发布时间】:2019-06-19 00:16:47
【问题描述】:

获取源代码(dynamodb.js):

const AWS = require("aws-sdk"); 
const Promise = require("bluebird");
const client = new AWS.DynamoDB.DocumentClient();
module.exports.db = (method, params) => {
  console.log("access dynamodb ");
  return Promise.fromCallback(cb => client[method](params, cb));
};

使用看起来像这样的测试(不想模拟 Promise.fromCallback):

describe("test", () => {
  const realAWS = require("aws-sdk");
  let fakePromise;
  let fakeDynamo;
  let dbClient;
  beforeAll(function() {
    fakePromise = jest.fn();
    fakeDynamo = {
      get: (params, cb) => {
        fakePromise(params, cb);
      }
    };
    realAWS.DynamoDB.DocumentClient = jest.fn(() => fakeDynamo);
    dbClient = require("../dynamodb");
  });
  test.only("Test successed", done => {
    let result = dbClient.db("get", null);
    console.log("access dynamodb ");
    expect(fakePromise).toHaveBeenCalled();
  });
});

但是当调整测试时,错误被解决了:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

如果有人可以帮助我?谢谢!

【问题讨论】:

    标签: node.js jestjs mocking aws-sdk bluebird


    【解决方案1】:

    您需要将client.get 方法的实现模拟为节点回调样式。这样Promise.fromCallback 方法会将回调样式转换为promise。

    此外,您需要在测试用例中触发回调。这就是出现超时错误的原因。

    例如

    dynamodb.js:

    const AWS = require('aws-sdk');
    const Promise = require('bluebird');
    
    const client = new AWS.DynamoDB.DocumentClient();
    
    module.exports.db = (method, params) => {
      console.log('access dynamodb');
      return Promise.fromCallback((cb) => client[method](params, cb));
    };
    

    dynamodb.test.js:

    const { db } = require('./dynamodb');
    const AWS = require('aws-sdk');
    
    jest.mock('aws-sdk', () => {
      const mClient = { get: jest.fn() };
      const mDynamoDB = {
        DocumentClient: jest.fn(() => mClient),
      };
      return { DynamoDB: mDynamoDB };
    });
    
    const mockClient = new AWS.DynamoDB.DocumentClient();
    
    describe('54360588', () => {
      afterAll(() => {
        jest.resetAllMocks();
      });
      it('should pass', async () => {
        mockClient.get.mockImplementationOnce((err, callback) => {
          callback(null, 'fake data');
        });
        const actual = await db('get', null);
        expect(actual).toBe('fake data');
        expect(mockClient.get).toBeCalledWith(null, expect.any(Function));
      });
    });
    

    带有覆盖率报告的单元测试结果:

     PASS  src/stackoverflow/54360588/dynamodb.test.js (10.74s)
      54360588
        ✓ should pass (28ms)
    
      console.log src/stackoverflow/54360588/dynamodb.js:177
        access dynamodb
    
    -------------|----------|----------|----------|----------|-------------------|
    File         |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    -------------|----------|----------|----------|----------|-------------------|
    All files    |      100 |      100 |      100 |      100 |                   |
     dynamodb.js |      100 |      100 |      100 |      100 |                   |
    -------------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        12.636s
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2021-11-04
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多