在mocha测试中使用webpack别名

问题描述 投票:48回答:8

我正在开发一个在React / Redux / Webpack中工作的Web应用程序,现在我开始将测试与Mocha集成。

我跟着the instructions for writing tests in the Redux documentation,但现在我遇到了我的webpack别名的问题。

例如,请查看我的一个动作创建者的此测试的导入部分:

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引用别名依赖时,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中。

reactjs npm mocha webpack redux
8个回答
37
投票

好吧所以我意识到我所有的别名都在src/目录中,所以我只需要修改我的npm run test脚本。

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

可能不适合所有人,但这解决了我的问题。


15
投票

您还可以使用我创作的babel插件:https://github.com/trayio/babel-plugin-webpack-alias它会将您的别名路径转换为相对路径,只需在您的.babelrc中加入一个babel插件即可。


4
投票

我也遇到了同样的问题,但是通过这个插件,我解决了它。

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" } ] 
    ]
}

3
投票

丹尼的答案很棒。但我的情况有点不同。我使用webpack的resolve.alias来使用src文件夹下的所有文件。

resolve: {
  alias: {
    '-': path.resolve(__dirname, '../src'),
  },
},

并为我自己的模块使用一个特殊的前缀,如下所示:

import App from '-/components/App';

为了测试这样的代码,我必须在mocha测试之前添加一个命令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:

我使用qazxsw poi,因为像-@这样的美丽角色不够安全。我找到了安全字符~的答案


2
投票

我想我解决了这个问题。你应该使用2个包:heremock-require

假设你有一个像这样的js文件:

app.js

proxyquire

你的测试代码应该像这样写:

app.test.js

import action1 from 'actions/youractions';   

export function foo() { console.log(action1()) }; 

文件树

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', () => {
    ...
  });
});

首先通过mock-require in函数模拟别名路径,然后在beforeEach函数中通过proxyquire模拟测试对象。


2
投票

我假设你的app.js |- test |- app.test.js 会有--require babel-register。你可以使用babel模块解析器插件mocha.opts。这允许您在.babelrc中设置别名,类似于您的webpack别名:

https://github.com/tleunen/babel-plugin-module-resolver

1
投票

我有完全相同的问题。似乎不可能在require.js或node的require中使用webpack别名。

我最终在单元测试中使用{ "plugins": [ ["module-resolver", { "alias": { "actions": "./src/actions", "constants": "./src/constants" } }] ] } 并且只是手动替换路径,如下所示:

mock-require

mock-require是一个很好的工具,因为你很可能无论如何都要模拟你的大部分依赖,而不是使用var mock = require('mock-require'); mock('actions/app', '../../src/actions/app'); 的实际脚本。


0
投票

将别名保留在像src这样的地方

config/webpack.common.js

然后安装resolve: { alias: { '~': path.resolve(__dirname, './../src/app') } }

babel-plugin-webpack-alias

然后在npm i babel-plugin-webpack-alias --save-dev 放:

.babelrc
© www.soinside.com 2019 - 2024. All rights reserved.