在 mocha 测试中使用 webpack 别名

IT技术 reactjs npm mocha.js webpack redux
2021-04-17 12:36:11

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

我按照Redux 文档中编写测试的说明进行操作,但现在我的 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 无法解析我的导入语句。

因为我还是 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 中。

6个回答

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

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

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

这是一个最优秀的解决方案,尤其是与模拟和代理需求相比!!
2021-05-26 12:36:11
我所有的东西也在src,但不知道如何实现你对我的测试脚本的修复:find ./src -name '*.test.js' | xargs mocha --require babel-core/register
2021-05-30 12:36:11
谢谢我试试这个。
2021-06-01 12:36:11
我已经开始使用mocha-webpack代替这种解决方法。github.com/zinserjan/mocha-webpack
2021-06-11 12:36:11
这对我的单次测试运行非常有用,但我无法成功地在别名目录中观看文件,您观看成功了吗?
2021-06-12 12:36:11

您还可以使用我编写的 babel 插件:https : //github.com/trayio/babel-plugin-webpack-alias 只需将 babel 插件包含到您的.babelrc.

此外,这个答案目前仅适用于边界链接。添加有关如何安装和使用插件的信息将解决此问题。
2021-05-25 12:36:11
我没有在生产中使用它,但我现在正在开发它。它似乎完全按预期进行。我是别名的粉丝,我认为使用 babel-plugin 来解决这个问题是要走的路。我没有看过来源或任何东西,但到目前为止工作正常。
2021-05-31 12:36:11
我点击了你的链接,根据那里的用户信息和这里的用户信息判断,看起来你是插件的作者,所以我进行了相应的编辑,因为提到你在答案中创建的软件而没有提及是违反 SO 规则的明确表示您创作了它。(这样做被认为是垃圾邮件,会受到严厉的惩罚。)如果不知何故,你不是作者,你可以回滚我的编辑,但一定要澄清,否则,下一个点击链接的人可能会做出与我相同的推断。
2021-06-15 12:36:11

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

https://www.npmjs.com/package/babel-plugin-webpack-aliases

您的“mocha”的执行命令未读取webpack.config.js,因此无法解析别名。
通过设置这个插件,webpack.config.js在编译时考虑使用“babel-core/register”。因此,别名在测试期间也将有效。

npm i -D babel-plugin-webpack-aliases

并将此设置添加到 .babelrc

{
    "plugins": [
        [ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ] 
    ]
}

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

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

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

import App from '-/components/App';

为了测试这样的代码,我必须ln -sf src test/alias/-在 mocha 测试之前添加一个命令,并使用NODE_PATH=./test/aliasDanny camp技巧。所以最终的脚本是这样的:

{   
  "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-requireproxyquire

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

应用程序.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模拟你的测试对象。