5

This is a bit shocking, but I've been long long time trying to find a simple example on how to test a silly react component using jest and typescript, and I am unable to succeed. I've had a look at: https://basarat.gitbooks.io/typescript/content/docs/testing/jest.html How to use react-test-renderer/shallow with typescript? How to see what the rendered React component looks like in the Jest unit test?

Nothing works. Most of the times I get

Test suite failed to run
'App' refers to a value, but is being used as a type here.

I'm new to react and jest. I've tried react-test-renderer and enzyme. At this stage I don't mind either, the most agnostic possible would be great.

What I have: This is my package.json

{
    "name": "web",
    "version": "1.0.0",
    "description": "mySample",
    "main": "index.js",
    "scripts": {
        "build-dev": "webpack --watch",
        "build": "webpack",
        "start-dev": "nodemon build/server.js",
        "start": "node build/server.js",
        "test": "jest"
    },
    "dependencies": {
        "express": "^4.17.1",
        "react": "^16.8.6",
        "react-dom": "^16.8.6"
    },
    "devDependencies": {
        "@types/enzyme": "^3.10.3",
        "@types/express": "^4.17.0",
        "@types/jest": "^24.0.16",
        "@types/node": "^12.6.9",
        "@types/react": "^16.8.24",
        "@types/react-dom": "^16.8.5",
        "enzyme": "^3.10.0",
        "jest": "^24.8.0",
        "nodemon": "^1.19.1",
        "ts-jest": "^24.0.2",
        "ts-loader": "^6.0.4",
        "typescript": "^3.5.3",
        "webpack": "^4.39.1",
        "webpack-cli": "^3.3.6",
        "webpack-node-externals": "^1.7.2"
    }
}

as you can see, I'd like to have strongly typed tests with typescript, and that's why I need enzyme types.

I have a silly react component App.tsx

import * as React from "react";

interface WelcomeProps {
    name: string;
}

const App: React.FC<WelcomeProps> = ({ name }) => {
    return <h1>Hello, {name}</h1>;
};

export default App;

And I want to have a test file App.test.ts where I simply test that given the <App name="whatever" /> renders, the DOM should have <h1>Hello, whatever</h1>

My attempt was:

import * as React from "react";
import App from "./App";
import { shallow } from "enzyme";

describe("App component", () => {
    it("returns the name passed as props", () => {
        const app = shallow(<App name="test" />);
        expect(app).toMatchSnapshot();
    });
});

and it fails with the above error, plus the VS Code displays error on the shallow argument as if it didn't understand JSX.

In case it's needed my jest.config.js is:

module.exports = {
    roots: ["<rootDir>/src"],
    transform: {
        "^.+\\.tsx?$": "ts-jest"
    }
};

It can't get simpler than this, yet I'm failing!

PS: The vast majority of the articles I find don't use typescript and type definitions, but this is something I want.

3 Answers 3

9

I know it's a old question, but I bumped into the same problem and it has a simple solution: your file name must have the .tsx extension for using jsx tag.

Sign up to request clarification or add additional context in comments.

Comments

1

Update: While this was accepted, the much better answer was provided by @alphamz below (.tsx vs .ts). That said I would still suggest create-react-app or create-next-app (much better in 2021) for React newbies who want to get up and running quickly, then you're starting with good time-tested settings.

Original answer: For someone new to React and Jest like yourself, I would strongly suggest starting with Create-React-App with the Typescript extension

https://facebook.github.io/create-react-app/docs/adding-typescript

This gives a good baseline for TS usage with jest support (has pretty strong app defaults as well)

yarn create react-app my-app --typescript

From there, use React-Testing-Library here: https://testing-library.com/docs/react-testing-library/intro

And you can write tests like this

import { render } from 'react-testing-library';

test('init GameTotaler', () => {
  const myName: string = 'foo';
  const { getByText } = render(
    <App name={foo} />
  );
  expect(getByText(`Hello, ${foo}`)).toBeTruthy();
});

@testing-library (that react-testing-library is part of) is extremely well written and supported by Kent C. Dodds, who is a remarkably strong author of React articles and on testing in general.

He has recently written why shallow rendering (which is what is done in Enzyme) can be an anti-pattern (at least for him) - https://kentcdodds.com/blog/why-i-never-use-shallow-rendering

Note that create-react-app does hide things inside its generated framework, but is well supported.

One strong plus - If you want to completely pull out of create-react-app once it's generated your codebase, you can run react-scripts eject and then you can see the secret sauce while still having a fully buildable codebase.

Hope this helps - Good luck!

1 Comment

Very interesting article about shallow rendering indeed
0

reactjs.org recommends React Testing Library.

If you want to use it with Jest and also need to test Typescript code, then you might have a look at crisp-react sample project. It has a React client and the tests can be found here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.