Using webpack aliases in mocha tests
Solution 1
Okay so I realized that everything I was aliasing was in the src/
directory, so I simply needed to modify my npm run test
script.
{
"scripts": {
"test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
Probably won't work for everyone, but that solved my issue.
Solution 2
You can also use a babel plugin I authored:
https://github.com/trayio/babel-plugin-webpack-alias
It will convert your aliased path to relative paths just by including a babel plugin to your .babelrc
.
Solution 3
I also encountered the same problem, but with this plugin I solved it.
https://www.npmjs.com/package/babel-plugin-webpack-aliases
The execution command of your "mocha" is not reading the webpack.config.js
, so it can not resolve the alias.
By setting this plugin, consider webpack.config.js
when compiling with "babel-core/register". As a result, the alias will also be valid during testing.
npm i -D babel-plugin-webpack-aliases
and add this setting to .babelrc
{
"plugins": [
[ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ]
]
}
Solution 4
I think I solved this problem. You should use 2 package: mock-require and proxyquire.
Assuming you have a js file like this:
app.js
import action1 from 'actions/youractions';
export function foo() { console.log(action1()) };
And your test code should write like this:
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
First mock the alias path by mock-require in before function, and mock your test object by proxyquire in beforeEach function.
Solution 5
Danny's answer is great. But my situation is a little bit different.
I used webpack's resolve.alias
to use all the files under src
folder.
resolve: {
alias: {
'-': path.resolve(__dirname, '../src'),
},
},
and use a special prefix for my own modules like this:
import App from '-/components/App';
To test code like this
I have to add a command ln -sf src test/alias/-
before mocha test and use the NODE_PATH=./test/alias
trick Danny camp up with. So the final script would be like this:
{
"scripts": {
"test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
PS:
I used -
because beautifal charactors like @
or ~
are not safe enough. I found the answer for safe characters here
![Danny Delott](https://i.stack.imgur.com/QSiK2.jpg?s=256&g=1)
Danny Delott
Frontend JavaScript engineer in the San Francisco Bay Area.
Updated on June 07, 2022Comments
-
Danny Delott about 2 years
I'm developing a web app at work in React/Redux/Webpack and am now starting to integrate testing with Mocha.
I followed the instructions for writing tests in the Redux documentation, but now I have run into an issue with my webpack aliases.
For example, take a look at the imports section of this test for one of my action creators:
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); }); }); });
As the comments suggest, mocha isn't able to resolve my import statements when they are referencing aliased dependencies.
Because I'm still new to webpack, here's my
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 }] } };
Also, I'm using the command
npm test
to run mocha, here's the script I'm using in mypackage.json
.{ "scripts": { "test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive" } }
So here's where I get stuck. I need to include the aliases from webpack into mocha when it runs.
-
Issam Zoli over 8 yearsI'm having the same issue, have you found a way to do this ?
-
Danny Delott over 8 yearsYep, just posted my answer. YMMV
-
-
zzm over 8 yearsIt seems no work when I use mock-require, error still say can't find module 'actions/xxx'.
-
Issam Zoli over 8 yearsThanks I'll try this.
-
azium over 8 yearsAll of my stuff is also in
src
, but not sure how to implement your fix to my test script:find ./src -name '*.test.js' | xargs mocha --require babel-core/register
-
Louis over 8 yearsI clicked on your link and judging by the user information there and your user information here, it looks like you are the author of the plugin, so I edited accordingly, because it is against SO rules to mention software you created in an answer without being explicit that you authored it. (Doing so is considered spam, and carries severe penalties.) If somehow you are not the author, you can rollback my edit but make sure to clarify because otherwise, the next person who clicks the link risks making the same inference I did.
-
Louis over 8 yearsAlso, this answer as it stands is borderline link-only. Adding information about how to install and use the plugin would fix this issue.
-
mikeycgto over 8 yearsThis is a most excellent solution, especially compared to mocking and proxying require!!
-
Ryan Ore about 8 yearsI'm not using this in production, but I am developing with it now. It seems to do exactly as expected. I'm a fan of alias, and I think using a babel-plugin to solve this problem is the way to go. I haven't looked at the source or anything, but so far works fine.
-
jmancherje almost 8 yearsthis works great for me for a single test run, but I'm not able to get successfully watch files in an aliased directory, have you had any success watching?
-
Danny Delott almost 8 yearsI've started using
mocha-webpack
instead of this workaround. github.com/zinserjan/mocha-webpack