testing-library / jest-dom

:owl: Custom jest matchers to test the state of the DOM

Home Page:https://testing-library.com/docs/ecosystem-jest-dom

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

v6: Getting "Cannot read properties of undefined (reading 'extend')"

EvHaus opened this issue · comments

  • @testing-library/jest-dom version: 6.0.0
  • node version: 20.3.1
  • npm (or yarn) version: 9.8.0

Relevant code or config:

// jest-setup.js
import '@testing-library/jest-dom';

// jest.config.js
setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],

What you did:

I'm attempting to upgrade from v8 and using setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'] to the newly documented steps of using setupFilesAfterEnv: ['<rootDir>/jest-setup.js'] and import '@testing-library/jest-dom';.

What happened:

Unfortunately it's not working for me. When I run my tests, I'm getting:

 TypeError: Cannot read properties of undefined (reading 'extend')

      2 |
      3 | // IMPORTANT: Avoid adding global mocks and shims in here. This file gets loaded
    > 4 | // ane executed for every single test spec. Adding code here slows down tests &
        | ^
      5 | // makes the code prone to memory leaks. It's better to add your mock to /jest
      6 | // and import it from your specific test file instead.
      7 |

      at Object.<anonymous> (../../node_modules/@testing-library/jest-dom/jest-globals.js:4:16)
      at Object.<anonymous> (jest.init.js:4:1)

Reproduction:

https://codesandbox.io/s/react-testing-library-v6-bug-f3wr8d?file=/package.json

Problem description:

See above

Suggested solution:

N/A

Your code sandbox does not appear to reflect the stack trace you posted. It looks like the stack trace is importing the /jest-globals entry point but the sandbox is using the default one.

Are you using @jest/globals in your actual repo?

Your code sandbox does not appear to reflect the stack trace you posted.

Apologies. I wasn't able to reproduce it in CodeSandbox exactly but given that it didn't work there either, I was hoping it was a similar problem.

Are you using @jest/globals in your actual repo?

No. Using Jest's default configuration (ie. globals are global).

No worries, I'm just confused why your stack trace says @testing-library/jest-dom/jest-globals.js:4:16 if you are not using @jest/globals.

Are you importing it like this in your jest.init.js file?

import '@testing-library/jest-dom';

That's what I'm confused about too. I'll try to provide as much detail as possible, but my setup is very similar to what's in the CodeSandbox other than I'm not using react-scripts.

  • I'm running jest via yarn jest
  • I have a jest.config.js file in my repo which has "setupFilesAfterEnv": ["<rootDir>/jest-setup.js"] set
  • In jest-setup.js the only thing I have is import "@testing-library/jest-dom";
  • In my tests I'm using default globals. I'm NOT using @jest/globals. Sample test:
import React from "react";
import { render } from "@testing-library/react";

test("React Testing Library works!", () => {
  const Test = () => <div>hello</div>;
  const { getByText } = render(Test);
  expect(getByText('hello')).toBeInTheDocument();
});

Should import '@testing-library/jest-dom'; be imported from a setupFiles file or a setupFilesAfterEnv file? I'm doing it from setupFilesAfterEnv as per the docs.

Should import '@testing-library/jest-dom'; be imported from a setupFiles file or a setupFilesAfterEnv file? I'm doing it from setupFilesAfterEnv as per the docs.

Based on my knowledge of Jest (and the Jest docs), it should be in setupFilesAfterEnv because expect gets reset in every test context. I'll try to repro this locally too now that the new version is published.

I have this working locally with @testing-library/jest-dom@6, @testing-library/dom@9, and jest@29:

jest.config.js

module.exports = {
  setupFilesAfterEnv: ["<rootDir>/jest-setup.js"],
  testEnvironment: "jsdom",
};

jest-setup.js

require("@testing-library/jest-dom");

example.spec.js

const { queryByText } = require("@testing-library/dom");

describe("example", () => {
  it("works", () => {
    const div = document.createElement("div");
    div.textContent = "Hello, world";
    document.body.appendChild(div);

    const found = queryByText(document.body, "Hello, world");
    expect(found).toBeInTheDocument();
  });
});
image

Apologies for wasting your time.

It took some time to find it but I had a rogue: import '@testing-library/jest-dom/extend-expect'; in one of my tests that was causing this problem.

No problem at all! Apparently extend-expect wasn't as "not widely used" as I thought... 😅

It didn't help that CodeSandbox seems to be pretty flaky with Jest config. Sometimes it simply wouldn't run the setup script.

Glad you solved the issue!