私は、React/Redux/Webpackで作業中のWebアプリを開発しており、Mochaとテストを統合し始めています。
Reduxのドキュメントにあるテストの作成手順 に従いましたが、今ではwebpackエイリアスの問題に遭遇しました。
たとえば、私のアクションクリエーターの1人に関するこのテストのインポートセクションを見てください。
import expect from 'expect' // resolves without an issue
import * as actions from 'actions/app'; // can't resolve this alias
import * as types from 'constants/actionTypes'; // can't resolve this alias
describe('Actions', () => {
describe('app',() => {
it('should create an action with a successful connection', () => {
const Host = '***************',
port = ****,
db = '******',
user = '*********',
pass = '******';
const action = actions.createConnection(Host, port, db, user, pass);
const expectedAction = {
type: types.CREATE_CONNECTION,
status: 'success',
payload: { Host, port, database, username }
};
expect(action).toEqual(expectedAction);
});
});
});
コメントが示唆しているように、mochaは、エイリアスされた依存関係を参照しているときにimportステートメントを解決できません。
私はまだwebpackが初めてなので、ここにwebpack.config.js
があります:
module.exports = {
devtool: 'eval-source-map',
entry: [
'webpack-hot-middleware/client',
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
resolve: {
extensions : ['', '.js', '.jsx'],
alias: {
actions: path.resolve(__dirname, 'src', 'actions'),
constants: path.resolve(__dirname, 'src', 'constants'),
/* more aliases */
}
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel'],
exclude: /node_modules/,
include: __dirname
}]
}
};
また、コマンドnpm test
を使用してmochaを実行しています。これは、package.json
で使用しているスクリプトです。
{
"scripts": {
"test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
だからここで私が立ち往生しています。 webpackの実行時にmochaにエイリアスを含める必要があります。
わかりましたので、エイリアシングを行っていたものはすべてsrc/
ディレクトリなので、単にnpm run test
スクリプト。
{
"scripts": {
"test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
おそらくすべての人にとってうまくいくわけではありませんが、それで私の問題は解決しました。
私が作成したbabelプラグインを使用することもできます: https://github.com/trayio/babel-plugin-webpack-alias エイリアスを変換します.babelrc
にbabelプラグインを含めるだけで、相対パスへのパス。
私も同じ問題に遭遇しましたが、このプラグインで解決しました。
https://www.npmjs.com/package/babel-plugin-webpack-aliases
「mocha」の実行コマンドはwebpack.config.js
を読み取っていないため、エイリアスを解決できません。
このプラグインを設定することにより、「babel-core/register」でコンパイルするときにwebpack.config.js
を考慮してください。結果として、エイリアスはテスト中にも有効になります。
npm i -D babel-plugin-webpack-aliases
この設定を.babelrc
に追加します
{
"plugins": [
[ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ]
]
}
ダニーの答えは素晴らしいです。しかし、私の状況は少し異なります。 webpackのresolve.alias
を使用して、src
フォルダーの下のすべてのファイルを使用しました。
resolve: {
alias: {
'-': path.resolve(__dirname, '../src'),
},
},
次のように、独自のモジュールに特別なプレフィックスを使用します。
import App from '-/components/App';
このようなコードをテストするには、mocha testの前にコマンドln -sf src test/alias/-
を追加し、NODE_PATH=./test/alias
トリックを使用してDannyがキャンプアップする必要があります。したがって、最終的なスクリプトは次のようになります。
{
"scripts": {
"test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
PS:
-
や@
などの美しい文字では十分に安全ではないため、~
を使用しました。安全な文字の答えを見つけました こちら
私はこの問題を解決したと思います。 2つのパッケージを使用する必要があります:mock-requireおよびproxyquire。
次のようなjsファイルがあると仮定します。
app.js
import action1 from 'actions/youractions';
export function foo() { console.log(action1()) };
テストコードは次のように記述する必要があります。
app.test.js
import proxyquire from 'proxyquire';
import mockrequire from 'mock-require';
before(() => {
// mock the alias path, point to the actual path
mockrequire('actions/youractions', 'your/actual/action/path/from/your/test/file');
// or mock with a function
mockrequire('actions/youractions', {actionMethod: () => {...}));
let app;
beforeEach(() => {
app = proxyquire('./app', {});
});
//test code
describe('xxx', () => {
it('xxxx', () => {
...
});
});
ファイルツリー
app.js
|- test
|- app.test.js
まず、before関数でmock-requireを使用してエイリアスパスをモックし、beforeEach関数でproxyquireを使用してテストオブジェクトをモックします。
私はあなたが--require babel-register
あなたのmocha.opts
。 babelモジュールリゾルバープラグインを使用できます https://github.com/tleunen/babel-plugin-module-resolver 。これにより、webpackエイリアスと同様に、.babelrcにエイリアスを設定できます。
{
"plugins": [
["module-resolver", {
"alias": {
"actions": "./src/actions",
"constants": "./src/constants"
}
}]
]
}
私はまったく同じ問題を抱えていました。 require.jsまたはノードのrequireでwebpackエイリアスを使用することは不可能のようです。
ユニットテストで mock-require を使用し、次のようにパスを手動で置き換えるだけでした。
var mock = require('mock-require');
mock('actions/app', '../../src/actions/app');
ほとんどの場合、src
の実際のスクリプトを使用する代わりに、ほとんどの依存関係をモックしたいので、mock-requireは優れたツールです。
エイリアスをconfig/webpack.common.js
などの1つの場所に保持するには
resolve: {
alias: {
'~': path.resolve(__dirname, './../src/app')
}
}
次にインストールします babel-plugin-webpack-alias
npm i babel-plugin-webpack-alias --save-dev
次に.babelrc
putに:
{
"presets": ["env"],
"plugins": [
["babel-plugin-webpack-alias", {
"config": "./config/webpack.common.js" // path to your webpack config
}]
]
}