Home > Software engineering >  Jest Mock an an error thrown and get the actual error from the catch
Jest Mock an an error thrown and get the actual error from the catch

Time:02-08

In code below I'm trying to test method getParameter for failure. Module A contains the method to test.

Module A.spec contains the test. Problem is that the test always passes, meaning it never hiuts the catch. I am mocking AWS.SSM to fail. What am I missing here?

Module 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

Module 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)
   }
 });

CodePudding user response:

You can use jest.spyOn(prm.AWS, 'SSM').mockReturnValue() to mock the SSM constructor and its instance.

E.g.

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 });
  });
});

Test result:

 PASS  stackoverflow/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/stackoverflow/71027434/a.spec.js:20:20
        at Generator.next (<anonymous>)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/stackoverflow/71027434/a.spec.js:8:71
        at new Promise (<anonymous>)
        at Object.<anonymous>.__awaiter (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/stackoverflow/71027434/a.spec.js:4:12)
        at Object.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/stackoverflow/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> (stackoverflow/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

package version:

"aws-sdk": "^2.875.0",
"jest": "^26.6.3",
  •  Tags:  
  • Related