首页 文章

在mocha测试中使用webpack别名

提问于
浏览
45

我正在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.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,这里's the script I' m在我的 package.json 中使用 .

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

所以这就是我被卡住的地方 . I need to include the aliases from webpack into mocha when it runs.

8 回答

  • 3

    Danny 's answer is great. But my situation is a little bit different. I used webpack' s 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:

    我使用 - 因为像 @~ 这样的美化字符不够安全 . 我找到了安全字符的答案here

  • 0

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

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

    可能不适用于所有人,但这解决了我的问题 .

  • 14

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

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

    将别名保留在一个地方,如 config/webpack.common.js

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

    然后安装babel-plugin-webpack-alias

    npm i babel-plugin-webpack-alias --save-dev
    

    然后在 .babelrc 放:

    {
        "presets": ["env"],
        "plugins": [
            ["babel-plugin-webpack-alias", {
                "config": "./config/webpack.common.js" // path to your webpack config
            }]
        ]
    }
    
  • 36

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

    我最终在单元测试中使用mock-require并且只是手动替换路径,如下所示:

    var mock = require('mock-require');
    
    mock('actions/app', '../../src/actions/app');
    

    mock-require是一个很好的工具,因为你很可能无论如何都要模拟你的大部分依赖,而不是使用 src 中的实际脚本 .

  • 1

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

  • 0

    我假设你的 mocha.opts 中会有 --require babel-register . 你可以使用babel模块解析器插件https://github.com/tleunen/babel-plugin-module-resolver . 这允许您在.babelrc中设置别名,类似于您的webpack别名:

    {
      "plugins": [
        ["module-resolver", {
           "alias": {
             "actions": "./src/actions",
             "constants": "./src/constants"
           }
        }]
      ]
    }
    
  • 4

    我想我解决了这个问题 . 你应该使用2个包: mock-requireproxyquire .

    假设你有一个像这样的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', () => {
        ...
      });
    });
    

    files tree

    app.js
      |- test
        |- app.test.js
    

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

相关问题