Utilize Jest to mock an error being thrown and retrieve the specific error message from the catch block

Below is a snippet of code where I am attempting to test the method getParameter for failure. The module A contains the method that needs to be tested.

The test is located in Module A.spec. The issue I am facing is that the test always passes, as it never reaches the catch block. I have tried mocking AWS.SSM to intentionally fail. What could I be overlooking?

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

Answer №1

You have the option to utilize

jest.spyOn(prm.AWS, 'SSM').mockReturnValue()
for mocking the SSM constructor along with its instance.

For example:

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",

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble grasping the purpose of app.use('/') in the Express framework

Below is the code snippet I am currently working with: // Initializing express, body-parser, mongodb, http, and cors var app = express(); app.use(cors()); app.use(express.urlencoded()); // Parse incoming JSON data from API clients app.use(express.json()); ...

Express Angular Node Template Render throwing an error: module 'html' not found

I am currently in the process of creating a web application using AngularJS with ui-router for routing via $stateProvider, ensuring that only the specified states are displayed in the ui-view. In my server.js file, I have set up an initial framework such ...

Adjust image size using Node.js and ImageMagick

How can I resize images before sending them to users in Node.js using Express? im = require("imagemagick") app.get('/image/:dossier/:id/:taille', function (req, res) { var image = __dirname + '/public/img/bibliotheque/'+req.params ...

Several directories for viewing in Node.js with Express

I have been researching different solutions, but I am still unsure about how to effectively integrate Express with multiple view folders. Imagine an Express application divided into distinct parts, each organized in its own subfolder: app +partA + ...

A guide on displaying data in a table using a select dropdown in a pug file and passing it to another pug file

After creating a single page featuring a select dropdown containing various book titles from a JSON file, I encountered an issue. Upon selecting a book and clicking submit (similar to this image), the intention was for it to redirect to another page named ...

The aggregation pipeline in nodeJS with mongoDB is failing to return any results, returning an empty array instead

Currently, I am enrolled in Jonas Schmeddtman's Node.js course where I am working on developing a tour App. However, I have encountered an issue where sending a request via Postman on the specified route results in an empty array instead of the expect ...

Implementing single sign-on across different domains with an express server, react client, and redirect functionality

To tackle the challenge at hand, I am working on developing a web application that involves a form submission to my express server. The process includes generating a token from an external endpoint post using the form value, utilizing this token from an ex ...

authorization for certain express routes using passport.js

Securing certain express routes with Passport.js authentication Steps for authenticating specific routes in Passport.js Looking for a method to authenticate particular routes using Passport.js Your assistance is greatly appreciated... ...

Creating Typescript libraries with bidirectional peer dependencies: A complete guide

One of my libraries is responsible for handling requests, while the other takes care of logging. Both libraries need configuration input from the client, and they are always used together. The request library makes calls to the logging library in various ...

Convert the date into a string format instead of a UTC string representation

I am currently working on a node.js project using TypeScript. In this project, I have a Slot class defined as follows: export class Slot { startTime: Date; constructor(_startTime: Date){ this.startTime = _startTime } } // Within a controller method ...

Error: postman expected an array instead of a string

I encountered an issue while trying to submit form data with multiple fields sharing the same name. The error message "TypeError: expected string but received array" keeps popping up. My suspicion is that the problem lies within Postman. I intend to have ...

How to Enhance GraphQL Mutation OutputFields with a Function Generator

I'm encountering issues while trying to incorporate a function generator within a GraphQL mutation. The function generator is utilized to streamline the promise chain inside the mutation. Prior to refactoring the code, everything was functioning corr ...

Deploying PhantomJS on Heroku

Running a node app on Heroku has been smooth sailing for me. I've implemented web scraping through selenium in Python, where my python script is called from the node app whenever needed. When testing locally on my Mac, everything functions perfectly a ...

The universal variable cannot be accessed within the internal function of socket.on() in Socket.io

The state in react called myChat is set globally. It is being displayed in the console using console.log(NEW), but not in NEW 2. I am unable to access it in the function socket.on() where the message is received by the user. Client side const socketNewM ...

Difficulty Implementing 'js-cookie' Library in NPM: Challenge with Managing Cookies

Encountering an issue with the js-cookie library while working on my Node.js application. I'm utilizing it to handle cookies, particularly setting a cookie called 'gameData' with the value 'value'. However, when attempting to retri ...

Is it feasible to run an "npm install" on code modifications made after the last version number update?

Hi there, I'm new to npm and have a question. Sorry for being a beginner. I am utilizing the node-dbus npm module, which is currently on version 0.2.0. However, I noticed that there have been some code changes added since the version was last updated ...

Configuring the Port for NodeJS Express App on Heroku

Currently, I am in the process of hosting my website on Heroku and configuring everything to ensure my app is up and running smoothly. However, each time I attempt to submit the form, undefined errors occur. For more details on the Undefined Errors and Co ...

What steps can I take to prevent receiving a 400 (Bad Request) error when using ajax PUT

Having an issue with sending data using JavaScript and AJAX. The objective is to send the data via PUT method to the server. var payload = 'id=' + id + '&brand=' + brand + '&model=' + model + '&country=' ...

Get image data from Next.JS API and show it in the web browser

I am looking to utilize my own next.js endpoints to request an image that I can then embed into my website. Currently, the issue I am facing is that the image seems to be immediately downloaded and does not display in the browser window. import type { Next ...

Error-throwing constructor unit test

In my code, I have implemented a constructor that takes in a configuration object. Within this constructor, I perform validations on the object. If the validation fails, I aim to throw an error that clearly describes the issue to the user. Now, I am wonde ...