Fighting with Jest / React / Babel / TypeScript / etc.

brokenrice
3 min readApr 5, 2023

--

This is just a rant when the tests of my project suddenly stop working after I upgrade react and react testing library to latest version. I’m getting the error TypeError: actImplementation is not a function with below setup

- react: 18.2.0
- react-dom: 18.2.0
- jest: 29.5.0
- @testing-library/react: 14.0.0

and many more deps and dev-deps that are not super relevant to my issue

TL;DR: It has nothing to do with version conflict. Rather it was me being silly and overlooked the global mock. In my defence, it was not very obvious at first 😛

Starting from scratch

After much hair scratching and head-banging, I decide to re-setup everything from scratch, to see where it might go wrong. I don’t use any utility scripts to bootstrap the project (e.g create-react-app), as they will often obfuscate some interesting details.

I simply bootstrap the project with npm init , no framework, no typescript, plain and clean.

Then following the guide https://jestjs.io/docs/tutorial-react#setup-without-create-react-app, I install recommended dependancies for babel and jest

npm install — save-dev babel-jest @babel/core @babel/preset-env

npm install --save-dev jest @babel/preset-react

and add the babel config file as per instruction

//babel.config.js
module.exports = {
presets: [
'@babel/preset-env',
['@babel/preset-react', {runtime: 'automatic'}],
],
};

Moment of truth, I write a very simple test to see if my setup works

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

describe("a", () => {
it("asdf", () => {
render(<div />);
});
});

Well, sure enough, it … doesn’t.

“document is not defined” error

N.B: if the error similar to the one below pops up, it’s likely that the preset @babel/preset-react is missing in the babel config file

Jest encountered an unexpected token

Configure Jest

The error was ReferenceError: document is not defined, so obviously I need to tell jest that I’m running test in the DOM environment. So I go head installing the required package and create a jest config file

npm i -D jest-environment-jsdom
// jest.config.js
const config = {
testEnvironment: "jsdom",
};

module.exports = config;

This time, the test run fine!

But when I copy over the exact babel and jest config to my original project, the test still fails, I wonder why …

‘Ah ha’ moment

So there must be something interfering with react-dom/test-utils module.

Turn out, in my old project, there was a workaround for the previous version of the react-testing-library. It was to mock the react-dom/test-utils module because of some old bugs in the library🤦‍♂

// __mocks__/react-dom/test-utils.js
// @see https://github.com/testing-library/react-testing-library/issues/315
module.exports = {};

That was the problem because under the hood of latest @testing-library/react version, it uses the act function from the react-dom/test-utils.

How about typescript

Since I’ve got that far, I decide to install typescript on my test project to see what would happen. (TBD)

Moral of the story

  • I think “starting-from-scratch” approach is very helpful when debugging a mysterious issue. You can eliminate a lot of uncertainty, and also relearn things that you think you already know.
  • When working with any test framework, know exactly what have been mocked, and where are those mocks being setup! This is super important because there’re so many different ways to mock a module.

--

--

brokenrice
brokenrice

Written by brokenrice

A developer who loves broken rices

No responses yet