Jest Mock 抛出错误并从捕获中获取实际错误

Jest Mock an an error thrown and get the actual error from the catch

在下面的代码中,我试图测试方法 getParameter 是否失败。模块 A 包含要测试的方法。

模块 A.spec 包含测试。问题是测试总是通过,这意味着它永远不会成功。我在嘲笑 AWS.SSM 失败。我在这里错过了什么?

模块 A:

const AWS = require ('aws-sdk')
exports.getParameter = async function (parameterName) {
    const params = {
        Name: parameterName,
        WithDecryption: true
    };
    const ssm = new AWS.SSM();
    try {
        const paramValue = await ssm.getParameter(params).promise();
        return paramValue.Parameter.Value;
    }
    catch (e) {
        console.log(e);
        throw new Error('Error while retrieving parameter value from pstore.\n' + e);
    }
};

exports.AWS = AWS

模块A.spec.js

  const prm = require('A')

  test('should handle error', () => {
      prm.AWS.SSM = jest.fn().mockImplementation(() => {
         throw new Error()
      })
    prm.getParameter = jest.fn()
    try{
      prm.getParameter("abc")
    }
   catch(e)
   {
     console.log(e)
   }
 });

您可以使用 jest.spyOn(prm.AWS, 'SSM').mockReturnValue() 模拟 SSM 构造函数及其实例。

例如

a.js:

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

exports.getParameter = async function (parameterName) {
  const params = {
    Name: parameterName,
    WithDecryption: true,
  };
  const ssm = new AWS.SSM();
  try {
    const paramValue = await ssm.getParameter(params).promise();
    return paramValue.Parameter.Value;
  } catch (e) {
    console.log(e);
    throw new Error('Error while retrieving parameter value from pstore.\n' + e);
  }
};

exports.AWS = AWS;

a.spec.js:

const prm = require('./a');

describe('71027434', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should get parameter value', async () => {
    const ssm = {
      getParameter: jest.fn().mockReturnThis(),
      promise: jest.fn().mockResolvedValueOnce({ Parameter: { Value: 'fake value' } }),
    };
    const SSMSpy = jest.spyOn(prm.AWS, 'SSM').mockReturnValue(ssm);
    const actual = await prm.getParameter('abc');
    expect(actual).toEqual('fake value');
    expect(SSMSpy).toBeCalledTimes(1);
    expect(ssm.getParameter).toBeCalledWith({ Name: 'abc', WithDecryption: true });
  });

  test('should handle error', async () => {
    const mError = new Error('network');
    const ssm = {
      getParameter: jest.fn().mockReturnThis(),
      promise: jest.fn().mockRejectedValueOnce(mError),
    };
    const SSMSpy = jest.spyOn(prm.AWS, 'SSM').mockReturnValue(ssm);
    await expect(prm.getParameter('abc')).rejects.toThrowError(
      'Error while retrieving parameter value from pstore.\n' + mError
    );
    expect(SSMSpy).toBeCalledTimes(1);
    expect(ssm.getParameter).toBeCalledWith({ Name: 'abc', WithDecryption: true });
  });
});

测试结果:

 PASS  Whosebug/71027434/a.spec.js (8.108 s)
  71027434
    ✓ should get parameter value (4 ms)
    ✓ should handle error (23 ms)

  console.log
    Error: network
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/Whosebug/71027434/a.spec.js:20:20
        at Generator.next (<anonymous>)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/Whosebug/71027434/a.spec.js:8:71
        at new Promise (<anonymous>)
        at Object.<anonymous>.__awaiter (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/Whosebug/71027434/a.spec.js:4:12)
        at Object.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/Whosebug/71027434/a.spec.js:19:42)
        at Object.asyncJestTest (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:45:12
        at new Promise (<anonymous>)
        at mapper (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:75:41

      at Object.<anonymous> (Whosebug/71027434/a.js:13:13)
          at Generator.throw (<anonymous>)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 a.js     |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.623 s, estimated 10 s

包版本:

"aws-sdk": "^2.875.0",
"jest": "^26.6.3",