React
コンポーネントをJest
+ Enzyme
でテストしようとしていますが、コンポーネントにSASS
ファイル(scss
)がある場合は発生するSyntaxError
。
これは私のSASSファイルの内容です:
.user-box {
width: 50px;
height: 50px;
}
そして、それをコンポーネントにインポートするだけです。
import React from 'react';
import './userBox.scss';
class MyComponent extends React.Component {
render() {
const style = {
borderRadius: '99px'
};
return (
<div>Hello World</div>
);
}
}
export default MyComponent;
私のテストの次のエラーメッセージ:
コメントするとimport './userBox.scss';
、テストは大丈夫です。
スタイルがインポートされているときにReact
+‵ Enzyme`を使用してJest
コンポーネントをテストする方法
Jest設定でdefine moduleNameMapper
を使用して、この種のファイルのモックを定義する必要があります。
使用しています identity-obj-proxy
。だからそれをインストールします
npm install identity-obj-proxy --save-dev
そしてそれにあなたの冗談の設定を追加します:
"moduleNameMapper": {
"^.+\\.(css|less|scss)$": "identity-obj-proxy"
}
スタックに Babel がある場合は、Babelの別のパッケージを使用してこれを修正できます: babel-jest
npm i --save-dev babel-jest
そしてあなたのjest設定ファイルに以下を追加します:
"moduleNameMapper": {
"^.+\\.(css|less|scss)$": "babel-jest"
}
私はしばらくの間、同様の問題の解決策を探していましたが、上記の解決策に出くわし続けました。
最初はうまくいかなかったようですが、Jestはpackage.jsonの「jest」に追加したものを単に無視していることに気づきました。私のセットアップにはjest.config.jsファイルが含まれています。そこに「moduleNameMapper」を追加すると、機能することがわかりました。だから今私のjest.test.config.jsは次のようになります:
module.exports = {
setupFiles: ["<rootDir>/testSetup.js"],
moduleNameMapper: {
"^.+\\.(css|scss)$": "identity-obj-proxy",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/fileMocks.js"
}
};
以前は以下の情報が入手できなかったので、 facebook/jestでプルリクエストをしました。マージされました 。
モジュールにインポートされたスタイルをスタブしたかったのです。
// module.js
import Style from '@/path/to/style.scss';
import App from './App';
そこで、スタイルスタブファイルを作成しました。
// test/unit/stubs/style.js
module.exports = '.style-stub{color:red;}';
次のjest.conf.js
をいじった後:
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1', // '@' alias
'^.*\\.scss$': '<rootDir>/test/unit/stubs/style.js',
}
moduleNameMapper
の順序が重要であることがわかりました。@
エイリアスルールが.scss
ルールの前に解決されていましたそのため、スタイルファイルは通常のモジュールとして読み込まれ、テストがクラッシュします。
解決策は、特定のルールを最初に置くことです。
moduleNameMapper: {
'^.*\\.scss$': '<rootDir>/test/unit/stubs/style.js',
'^@/(.*)$': '<rootDir>/src/$1',
}