How do I resolve a UnhandledPromiseRejectionWarning with Jest in node.js server

Viewed 8175

My tests are passing correctly but I keep receiving a UnhandledPromiseRejectionWarning. Any ideas on how to resolve this please? I've tried many solution but none seem to work.

node:32535) UnhandledPromiseRejectionWarning: Error: expect(received).toMatchObject(expected)

Matcher error: received value must be a non-null object

Received has value: undefined (node:32535) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:32535) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This my test file:

jest.mock("./http");
const { fetchAllUsersData } = require("./http");

test("Data returned from server should be a list of users ", async () => {
  fetchAllUsersData()
    .catch((errorMessage) => expect(errorMessage).toThrowError(Error))
    .then((usersRetrieved) => {
      let users = usersRetrieved[0];
      let userModel = {
        id: 1,
        first_name: "Peggy",
        last_name: "Poppins",
        email: "mpoppins0@squidoo.com",
        ip_address: "192.54.212.191",
        latitude: 34.003135,
        longitude: -117.7228641222,
      };

      expect(users).toMatchObject(userModel);
    });
});

This is my file inside the mock folder:

      const fetchAllUsersData = () => {
        return Promise.resolve({
          data: [
            {
              id: 1,
              first_name: "Merry",
              last_name: "Poppins",
              email: "mpoppins0@squidoo.com",
              ip_address: "192.54.212.191",
              latitude: 34.003135,
              longitude: -117.7228641,
            },
            {
              id: 15,
              first_name: "George",
              last_name: "Foreman",
              email: "gforeman@clear.com",
              ip_address: "12.564.124.521",
              latitude: 23.592254,
              longitude: 125.454227,
            },
          ],
        });
      };

      exports.fetchAllUsersData = fetchAllUsersData;
1 Answers

The reason for this error is that a promise wasn't chained to be returned from the test. A floating promise is an antipattern. async..await allows to achieve this with a bit less discipline than it's required for raw promises. It usually doesn't make sense to use raw promises together with async. Also, it doesn't make sense to test both successful and failed requests in the same test, an expected response is supposed to be predetermined.

expect(errorMessage).toThrowError(Error) will only work if errorMessage is a function that synchronously throws an error. It won't work as expected if fetchAllUsersData rejects with errorMessage object.

It likely should be in one test:

test("...", async () => {
  const usersRetrieved = await fetchAllUsersData();
  ...
  expect(users).toMatchObject(userModel);
});

In another test:

test("...", async () => {
  await expect(fetchAllUsersData()).rejects.toThrowError(Error);
});

Also, tests don't serve a good purpose if you test your own test code supplied in __mock__. They should test production code.

Related