在 mocha 测试中使用 webpack 别名
Using webpack aliases in mocha tests
我正在 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 在引用别名依赖项时无法解析我的导入语句。
因为我还是 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"
}
}
这就是我卡住的地方。 我需要在 运行s 时将 webpack 的别名包含到 mocha 中。
我遇到了完全相同的问题。在 require.js 或节点的要求中使用 webpack 别名似乎是不可能的。
我最终在单元测试中使用了 mock-require,只是手动替换了路径,如下所示:
var mock = require('mock-require');
mock('actions/app', '../../src/actions/app');
mock-require 是一个很好的工具,因为很可能您无论如何都想模拟大部分依赖项,而不是使用来自 src
.
的实际脚本
我想我解决了这个问题。您应该使用 2 个包:mock-require and 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 模拟你的测试对象。
好的,所以我意识到我使用别名的所有内容都在 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
它会将您的别名路径转换为相对路径,只需将 babel 插件添加到您的 .babelrc
.
丹尼的回答很棒。但是我的情况有点不同。
我使用 webpack 的 resolve.alias
来使用 src
文件夹下的所有文件。
resolve: {
alias: {
'-': path.resolve(__dirname, '../src'),
},
},
并为我自己的模块使用特殊前缀,如下所示:
import App from '-/components/App';
像这样测试代码
我必须在 mocha 测试之前添加一个命令 ln -sf src test/alias/-
并使用 Danny 的 NODE_PATH=./test/alias
技巧。所以最终的脚本是这样的:
{
"scripts": {
"test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
PS:
我用了-
,因为像@
或~
这样的美字不够安全。我找到了安全字符的答案 here
我也遇到了同样的问题,但是用这个插件解决了。
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" } ]
]
}
我假设您的 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"
}
}]
]
}
像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
}]
]
}
我正在 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 在引用别名依赖项时无法解析我的导入语句。
因为我还是 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"
}
}
这就是我卡住的地方。 我需要在 运行s 时将 webpack 的别名包含到 mocha 中。
我遇到了完全相同的问题。在 require.js 或节点的要求中使用 webpack 别名似乎是不可能的。
我最终在单元测试中使用了 mock-require,只是手动替换了路径,如下所示:
var mock = require('mock-require');
mock('actions/app', '../../src/actions/app');
mock-require 是一个很好的工具,因为很可能您无论如何都想模拟大部分依赖项,而不是使用来自 src
.
我想我解决了这个问题。您应该使用 2 个包:mock-require and 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 模拟你的测试对象。
好的,所以我意识到我使用别名的所有内容都在 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
它会将您的别名路径转换为相对路径,只需将 babel 插件添加到您的 .babelrc
.
丹尼的回答很棒。但是我的情况有点不同。
我使用 webpack 的 resolve.alias
来使用 src
文件夹下的所有文件。
resolve: {
alias: {
'-': path.resolve(__dirname, '../src'),
},
},
并为我自己的模块使用特殊前缀,如下所示:
import App from '-/components/App';
像这样测试代码
我必须在 mocha 测试之前添加一个命令 ln -sf src test/alias/-
并使用 Danny 的 NODE_PATH=./test/alias
技巧。所以最终的脚本是这样的:
{
"scripts": {
"test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
PS:
我用了-
,因为像@
或~
这样的美字不够安全。我找到了安全字符的答案 here
我也遇到了同样的问题,但是用这个插件解决了。
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" } ]
]
}
我假设您的 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"
}
}]
]
}
像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
}]
]
}