在摩卡testing中使用webpack别名
我正在React / Redux / Webpack中开发一个Web应用程序,现在我正在开始与Mocha集成testing。
我按照在Redux文档中编写testing的说明进行操作 ,但是现在我遇到了一个与我的webpack别名有关的问题。
例如,看看我的一个动作创build者的testing的import部分:
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); }); }); });
正如评论所言,摩卡在引用别名依赖关系时无法解决我的导入语句。
因为我还是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中的别名join摩卡。
好吧,所以我意识到我所有的别名都在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它会将您的别名path转换为相对path,只需在您的.babelrc
一个babel插件即可。
我想我解决了这个问题。 你应该使用2包: 模拟需求和proxyquire 。
假设你有一个这样的js文件:
app.js
import action1 from 'actions/youractions'; export function foo() { console.log(action1()) };
而你的testing代码应该这样写:
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
首先在前一个函数中用mock-require模拟别名path,然后在beforeEach函数中用proxyquire模拟你的testing对象。
丹尼的答案很好。 但是我的情况有点不同 我使用webpack的resolve.alias来使用src
文件夹下的所有文件。
resolve: { alias: { '-': path.resolve(__dirname, '../src'), }, },
并为我自己的模块使用一个特殊的前缀,如下所示:
import App from '-/components/App';
为了testing这样的代码,我必须在mochatesting之前添加一个命令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:
我用-
因为像@
或~
这样的美化字符不够安全。 我在这里find了安全字符的答案
我有完全相同的问题。 在require.js中或节点的require中使用webpack别名似乎是不可能的。
我最终在unit testing中使用了mock-require ,只是手动replacepath,如下所示:
var mock = require('mock-require'); mock('actions/app', '../../src/actions/app');
mock-require是一个很好的工具,因为大多数情况下你可能想要嘲笑你的大部分依赖,而不是使用src
的实际脚本。
我也遇到了同样的问题,但是用这个插件我解决了它。
https://www.npmjs.com/package/babel-plugin-webpack-aliases
你的“摩卡”的执行命令不读取webpack.config.js
,所以它不能parsing别名。
通过设置这个插件,在编译“babel-core / register”时考虑webpack.config.js
。 结果,别名在testing期间也是有效的。
npm i -D babel-plugin-webpack-aliases
并将此设置添加到.babelrc
{ "plugins": [ [ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ] ] }