Skip to content

Instantly share code, notes, and snippets.

@jackawatts
Last active June 14, 2023 08:09
Show Gist options
  • Save jackawatts/1c7a8d3c277ccf4e969675002fe35bc9 to your computer and use it in GitHub Desktop.
Save jackawatts/1c7a8d3c277ccf4e969675002fe35bc9 to your computer and use it in GitHub Desktop.
Getting started with Typescript, React and Jest

Getting Started

  1. Install:
  • jest: npm install --save-dev jest
  • ts-jest: npm install --save-dev ts-jest @types/jest
  1. Modify package.json
"jest": {
  "transform": {
    "^.+\\.tsx?$": "ts-jest"
  },
  "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  "moduleFileExtensions": [
    "ts",
    "tsx",
    "js",
    "jsx",
    "json",
    "node"
  ]
},
"scripts": {
  "test": "jest"
}
  1. Running tests npm test

  2. Ensuring tests are excluded from webpack

Modify webpack.config.js

{ test: /\.tsx?$/, exclude: /\.test.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' },

Writing the Tests

Test Setup

modify package.json to the appropriate location of your setup file eg. ClientApp/setupTests.ts

"jest": {
    ...
    "setupTestFrameworkScriptFile": "<rootDir>/ClientApp/setupTests.ts",
    ...
}

Snapshot tests

i. Install react-test-renderer

npm install --save-dev react-test-renderer @types/react-test-renderer

ii. Write your tests!

import * as React from "react";
import * as renderer from "react-test-renderer";
import { SubjectToBeTested } from "./SubjectToBeTested";

it("SubjectToBeTested renders correctly", () => {
  const props = { className: "test", value: true, onSelectChanged: (value: boolean) => { return; } };
  const tree = renderer
    .create(<SubjectToBeTested {...props} />)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

DOM tests

i. Install Enzyme:

npm install --save-dev enzyme @types/enzyme
npm install --save-dev enzyme-adapter-react-16 @types/enzyme-adapter-react-16

ii. Modify setupTests.ts

import { configure } from "enzyme";
import React16Adapter from "enzyme-adapter-react-16";

configure({ adapter: new React16Adapter() });

iii. Write your tests!

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

it("SubjectToBeTested calls onSelectChanged", () => {
  let newValue = false;
  const props = { className: "test", value: true, onSelectChanged: (value: boolean) => { newValue = value; } };
  const sut = shallow(<SubjectToBeTested {...props} />);

  sut.find("select").simulate("change", {target: { value : "true"}});
  expect(newValue).toEqual(true);
  sut.find("select").simulate("change", {target: { value : "false"}});
  expect(newValue).toEqual(false);
});

Configuring for VSTS

  1. Install jest-junit: npm install --save-dev jest-junit
  2. Update Jest config package.json
 "jest": {
    "testResultsProcessor": "jest-junit",
    ...
 }
  1. Ensure junit.xml is excluded via .gitignore ;)
  2. Add npm task to the build
  • Command: custom
  • Command and arguments: test
  1. Add Publish Results task to the build
  • Test result format: JUnit
  • Test result files: **/junit.xml

Troubleshooting

  • Problems with imports? Try "allowSyntheticDefaultImports": true, in tsconfig.json
  • DevDependency grief? Try "no-implicit-dependencies": [true, "dev"], in tslint.json
@charlypoly
Copy link

Regarding using Enzyme with TypeScript, if you have the following error:

enzyme_adapter_react_16_1.default is not a constructor

This ticket provides a solution:

Based on the above answers, what i did to solve this is:

yarn add --dev types/enzyme-adapter-react-16 types/enzyme and changed imports to

import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';

@Enoumy
Copy link

Enoumy commented Mar 20, 2020

"jest": {
"transform": {
"^.+\.tsx?$": "ts-jest"
},
"testRegex": "(/tests/.*|(\.|/)(test|spec))\.(jsx?|tsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},

This is wrong, it needs the to be wrapped around "jest"

@Enoumy
Copy link

Enoumy commented Mar 20, 2020

"jest": {
"transform": {
"^.+.tsx?$": "ts-jest"
},
"testRegex": "(/tests/.*|(.|/)(test|spec)).(jsx?|tsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},

This is wrong, it needs the to be wrapped around "jest"

OOOOOOOOH never mind it's just not showing in the rendered readme since you placed the jest thing at the same line as the ``` ticks.

@jackawatts
Copy link
Author

I've updated the md so other people reading this moving forward won't make the same mistake

@murtazamzk
Copy link

murtazamzk commented Mar 18, 2021

`TypeError: $export is not a function

  1 | /* eslint-env jest */
  2 |
> 3 | import React from "react";`

I am getting a import error. tsconfig below

```

{
"include": ["src", "types", "@types/jest"],
"exclude": ["node_modules"],
"allowSyntheticDefaultImports": true,
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"jsx": "react",
"lib": ["es2015", "dom"],
"baseUrl": "./",
"paths": {
"@src/": ["./src/app/"],
},
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"noImplicitAny": false,
"esModuleInterop": true
}
}

@tlehtimaki
Copy link

Just stumbled upon these and as I recently moved away from Enzyme and Sinon in favor of just vanilla jest and testing-library. I have to say that I highly recommend to think twice before using Enzyme (or Sinon) nowadays. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment