Create-react-app + TypeScriptアプリでテストを実行するように構成を設定しています(from from ejected)。私はjest +酵素を使用しています。 tsconfig.jsonでbaseUrl='./src'
を設定したため、モジュールをインポートするときに絶対パスを使用できます。たとえば、これは私のファイルの1つにある典型的なimportステートメントです。
import LayoutFlexBoxItem from 'framework/components/ui/LayoutFlexBoxItem';
パスは絶対パス(/ srcフォルダーから)であり、相対パスではないことがわかります。これは、デバッグモード(yarn start
)で実行すると正常に機能します
しかし、テスト(yarn test
)を実行すると、次のエラーが表示されます。
Cannot find module 'framework/components/Navigation' from 'index.tsx'
そのため、tsconfig.jsonでjestを設定しましたが、jestはこの絶対パスを解決できないようです。これは私のtsconfig.jsonです:
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"baseUrl": "./src"
},
"exclude": [
"node_modules",
"build",
"dist",
"config",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}
これで、プロジェクトのルートに生成されたtsconfig.test.json
があることがわかります。これは、テストに使用されるts構成です。そして、その内容は次のとおりです。
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}
ご覧のとおり、ここでは「モジュール」はcommonjs
ですが、デフォルトの構成ではesnext
です。これが1つの理由でしょうか?
Jestと絶対パスを使用してTypeScriptプロジェクトを単体テストできる人はいますか?またはこれは既知のバグですか?デフォルトの構成から削除したので、webpackの構成に入れるべき設定はありますか?
ご意見とご提案をお寄せいただきありがとうございます。
私は同じ問題に苦しんでいましたが、実際には簡単な変更でうまくいくようです。
jest.config.js
のmoduleDirectories
フィールドを更新しました
前
moduleDirectories: ['node_modules']
後
moduleDirectories: ['node_modules', 'src']
それが役に立てば幸い、
アントワーヌ
ModuleNameMapperがどのように機能するかを以下に示します。
私のtsconfigに以下の設定を使用します:
"paths": {
"@App/*": [
"src/*"
],
"@Shared/*": [
"src/Shared/*"
]
},
ModuleNameMapperは次のとおりです。
"moduleNameMapper": {
"@App/(.*)": "<rootDir>/src/$1",
"@Shared/(.*)": "<rootDir>/src/Shared/$1"
}
私の解決策は、
"jest": {
"moduleDirectories": [
"node_modules",
"src"
],
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"roots": [
"src"
],
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"moduleNameMapper": {
"src/(.*)": "<rootDir>/src/$1"
}
}
TypeScriptでReactを使用しています。react-scripts-ts test --env=jsdom
from npm test
および追加jest --watch
を追加した後のデフォルトのテストとしてjest.config.js
これらの指示に従って私のプロジェクトに https://basarat.gitbooks.io/TypeScript/docs/testing/jest.html
そして、@ Antonie Laffargueが言及している構成を使用しました(プロパティmoduleDirectories: ['node_modules', 'src']
)、それは完全に動作します。
ここで多くの人が指摘したように、jest.config.js
のmoduleNameMapper
はtsconfig.json
で指定されたパスを定義する必要があります。たとえば、次のように定義されたtsconfig.json
にパスがある場合
// tsconfig.json
{
...
"baseUrl": "src",
"paths": {
"@alias/*": [ 'path/to/alias/*' ]
}
...
}
jest.config.js
は、これらのパスをmoduleNameMapper
で次の形式で提供する必要があります。
// jest.config.js
module.exports = {
'roots': [
'<rootDir>/src'
],
'transform': {
'^.+\\.tsx?$': 'ts-jest'
},
'moduleNameMapper': {
'@alias/(.*)': '<rootDir>/src/path/to/alias/$1'
}
};
jest.config.js
を改善して、tsconfig.json
で定義されたパスを自動的に変換できます。以下が Gist code snippet です:
// jest.config.js
function makeModuleNameMapper(srcPath, tsconfigPath) {
// Get paths from tsconfig
const {paths} = require(tsconfigPath).compilerOptions;
const aliases = {};
// Iterate over paths and convert them into moduleNameMapper format
Object.keys(paths).forEach((item) => {
const key = item.replace('/*', '/(.*)');
const path = paths[item][0].replace('/*', '/$1');
aliases[key] = srcPath + '/' + path;
});
return aliases;
}
const TS_CONFIG_PATH = './tsconfig.json';
const SRC_PATH = '<rootDir>/src';
module.exports = {
'roots': [
SRC_PATH
],
'transform': {
'^.+\\.tsx?$': 'ts-jest'
},
'moduleNameMapper': makeModuleNameMapper(SRC_PATH, TS_CONFIG_PATH)
};
同様の問題がありました。これが皆さんの時間を割くのに役立つことを願っています。
私の問題:
エラーはNODE_PATHの異なる値が原因であることがわかりました。そのため、テスト実行時に設定しました。
ここで問題と修正を再現しました: https://github.com/alessandrodeste/...
これがテストに副作用をもたらすかどうかはわかりません。フィードバックがあれば教えてください;)
ts-jestはこの問題を完全に解決できます!
https://kulshekhar.github.io/ts-jest/user/config/#paths-mapping
jest.config.jsを次のように変更します。
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.json');
module.exports = {
preset: 'ts-jest',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths)
}
おそらくjest configのmoduleNameMapper
機能が必要でしょう。カスタムインポート名前空間を実際のモジュールの場所にマップします。
こちらの公式ドキュメントをご覧ください。
https://facebook.github.io/jest/docs/en/configuration.html#modulenamemapper-object-string-string