web-dev-qa-db-ja.com

mochaテストでwebpackエイリアスを使用する

私は、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にエイリアスを含める必要があります。

50
Danny Delott

わかりましたので、エイリアシングを行っていたものはすべてsrc/ディレクトリなので、単にnpm run testスクリプト。

{   
  "scripts": {
    "test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
  }
}

おそらくすべての人にとってうまくいくわけではありませんが、それで私の問題は解決しました。

37
Danny Delott

私が作成したbabelプラグインを使用することもできます: https://github.com/trayio/babel-plugin-webpack-alias エイリアスを変換します.babelrcにbabelプラグインを含めるだけで、相対パスへのパス。

15
adriantoine

私も同じ問題に遭遇しましたが、このプラグインで解決しました。

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" } ] 
    ]
}
5
Yuki Hirano

ダニーの答えは素晴らしいです。しかし、私の状況は少し異なります。 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:

-@などの美しい文字では十分に安全ではないため、~を使用しました。安全な文字の答えを見つけました こちら

3
Stupidism

私はこの問題を解決したと思います。 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を使用してテストオブジェクトをモックします。

2
zhaozhiming

私はあなたが--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"
       }
    }]
  ]
}
2
Northern

私はまったく同じ問題を抱えていました。 require.jsまたはノードのrequireでwebpackエイリアスを使用することは不可能のようです。

ユニットテストで mock-require を使用し、次のようにパスを手動で置き換えるだけでした。

var mock = require('mock-require');

mock('actions/app', '../../src/actions/app');

ほとんどの場合、srcの実際のスクリプトを使用する代わりに、ほとんどの依存関係をモックしたいので、mock-requireは優れたツールです。

1
Ilya Kogan

エイリアスを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
        }]
    ]
}
0
ScorpAL