TypeError: Cannot destructure property ‘enqueueSnackbar’

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error TypeError: Cannot destructure property ‘enqueueSnackbar’ on this date .

I have a Jest unit test that is testing an error from a mocked API call to ensure that the error message is displayed on the page. In my actual file, I’m using notistack to display the error messages. I’ve not displayed the full API request because I don’t think it’s relevant so in short, it is the following:

myComponent.js:

import { useSnackbar } from 'notistack';

const myComponent = props => {
  const { enqueueSnackbar } = useSnackbar()

  //make an API call to an endpoint
  ...
  if (response.ok) enqueueSnackbar("API Success", { variant: "success" });
  else enqueueSnackbar("API Failed", { variant: "error" });
}

As a result of this, I am testing the above on my unit test. Again, I won’t paste the whole unit test because I don’t think it’s relevant, but something similar to:

myComponent.test.js

import { render, screen } from "@testing-library/react"

test("testing error message on API call", async () => {
  // mock the API call to return a 500 <- this works fine

  render(<myComponent />)

  // ensure that the error message is displayed in the screen
  expect(screen.queryByText(/API Failed/)).toBeInTheDocument();
});

Doing the above, I get an error:

TypeError: Cannot destructure property ‘enqueueSnackbar’ of ‘(0 , _notistack.useSnackbar)(…)’ as it is undefined

If I simply include something like the following, enqueueSnackbar() will be defined but the test still fails because the message is null.

const mockEnqueue = jest.fn();

jest.mock('notistack', () => ({
  ...jest.requireActual('notistack'),
  useSnackbar: () => {
    return {
      enqueueSnackbar: mockEnqueue
    };
  }
}));

However, I don’t even want to mock the snackbar because I want to test the actual display message for each specific scenario (there are multiple).

Answer

Wrapping the render() within my unit test with a SnackbarProvider resolved the issue.

import { SnackbarProvider } from "notistack"
import { render, screen } from "@testing-library/react"

test("testing error message on API call", async () => {
  /* mock the API call to return a 500 <- this works fine */

  render(
    <SnackbarProvider>
      <myComponent />
    </SnackbarProvider>
  )

  /* ensure that the error message is displayed in the screen */
  expect(screen.queryByText(/API Failed/)).toBeInTheDocument();
});