Closed13

Next.js にテストを導入する

Wataru TaguchiWataru Taguchi

Quick Start

公式にサンプルが用意されている

npx create-next-app --example with-jest with-jest-app

Manual setup

既存に導入するときはこっちなので、今回はこっちを叩く

npm install --save-dev jest babel-jest @testing-library/react @testing-library/jest-dom identity-obj-proxy react-test-renderer
Wataru TaguchiWataru Taguchi

Configuring Jest

jest.config.js
module.exports = {
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/node_modules/**',
  ],
  moduleNameMapper: {
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
    '^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
    '^.+\\.(jpg|jpeg|png|gif|webp|svg)$': `<rootDir>/__mocks__/fileMock.js`,
  },
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
  },
  transformIgnorePatterns: [
    '/node_modules/',
    '^.+\\.module\\.(css|sass|scss)$',
  ],
}

collectCoverageFrom

カバレッジの設定

https://jestjs.io/ja/docs/configuration#collectcoveragefrom-array

moduleNameMapper

CSS モジュールや画像などをモックする

https://jestjs.io/ja/docs/configuration#modulenamemapper-objectstring-string--arraystring

https://jestjs.io/ja/docs/webpack#cssモジュールのモック

https://jestjs.io/ja/docs/webpack#静的アセットの管理

testPathIgnorePatterns

テストを無視するパス

https://jestjs.io/ja/docs/configuration#testpathignorepatterns-arraystring

transform

babel を使う設定

https://jestjs.io/ja/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object

transformIgnorePatterns

transform しないパス

https://jestjs.io/ja/docs/configuration#transformignorepatterns-arraystring

Wataru TaguchiWataru Taguchi

CSS や画像のモック

CSS や画像はテストに使わないが、インポートされるとエラーになる可能性があるのでモックを作る

__mocks__/fileMock.js
(module.exports = "test-file-stub")
__mocks__/styleMock.js
module.exports = {};
Wataru TaguchiWataru Taguchi

Absolute Imports and Module Path Aliases

もし、絶対パスの指定をしているのであれば、Jest に設定を書く必要がある

https://nextjs.org/docs/advanced-features/module-path-aliases

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/components/*": ["components/*"]
    }
  }
}
jest.config.js
moduleNameMapper: {
  '^@/components/(.*)$': '<rootDir>/components/$1',
}

導入しようとしている Next.js のプロジェクトは設定をしているので設定を追加

Wataru TaguchiWataru Taguchi

テストの作成

lib/util/zeroFill.ts
export const zeroFill = (val: number): string => {
  return (`0${val}`).slice(-2);
};
lib/util/__tests__/zeroFill.spec.ts
import { zeroFill } from '../zeroFill';

describe('zeroFill', () => {
  it('1桁', () => {
    expect(zeroFill(1)).toEqual('01');
  });
  it('2桁', () => {
    expect(zeroFill(11)).toEqual('11');
  });
});

ESLint に 'describe' is not defined., 'it' is not defined., 'expect' is not defined. と怒られる

eslint-plugin-jest を導入する

https://www.npmjs.com/package/eslint-plugin-jest

npm install --save-dev eslint-plugin-jest

設定を追加し完了

.eslintrc.js
{
  "env": {
    "jest/globals": true
  },
  "plugins": ["jest"]
}

npm run test で無事成功

 PASS  lib/util/__tests__/zeroFill.spec.ts
  zeroFill
    ✓ 1桁 (2 ms)
    ✓ 2桁

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.224 s, estimated 2 s
Ran all test suites related to changed files.

Watch Usage: Press w to show more.
Wataru TaguchiWataru Taguchi

カバレッジ

package.json
"scripts": {
  "test:coverage": "jest --coverage"
}

実行すると .next, coverage, public 配下も見ているので無視する設定を追加

jest.config.js
collectCoverageFrom: [
    '!**/.next/**',
    '!**/coverage/**',
    '!**/public/**',
  ],
このスクラップは2021/08/29にクローズされました