Je développe une application Web au travail dans React/Redux/Webpack et je commence maintenant à intégrer les tests avec Mocha.
J'ai suivi les instructions pour écrire des tests dans la documentation Redux , mais je suis maintenant confronté à un problème avec les alias de mon webpack.
Par exemple, jetez un œil à la section des importations de ce test pour l'un de mes créateurs d'action:
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);
});
});
});
Comme le suggèrent les commentaires, mocha n'est pas en mesure de résoudre mes instructions d'importation lorsqu'elles font référence à des dépendances avec alias.
Comme je ne connais pas encore le WebPack, voici mon 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
}]
}
};
De plus, j'utilise la commande npm test
pour exécuter mocha, voici le script que j'utilise dans mon package.json
.
{
"scripts": {
"test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
Alors voici où je suis coincé. J'ai besoin d'inclure les alias de webpack dans mocha quand il s'exécute.
D'accord, j'ai réalisé que tout ce que je cherchais était dans le répertoire src/
. Il me fallait donc simplement modifier mon script npm run test
.
{
"scripts": {
"test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
Cela ne fonctionnera probablement pas pour tout le monde, mais cela a résolu mon problème.
Vous pouvez également utiliser un plugin babel dont j'ai été l'auteur: https://github.com/trayio/babel-plugin-webpack-alias Il convertira votre chemin d'accès alias en chemins relatifs simplement plugin babel à votre .babelrc
.
J'ai aussi rencontré le même problème, mais avec ce plugin je l'ai résolu.
https://www.npmjs.com/package/babel-plugin-webpack-aliases
La commande d'exécution de votre "mocha" ne lit pas le webpack.config.js
, elle ne peut donc pas résoudre l'alias.
En définissant ce plugin, tenez compte de webpack.config.js
lors de la compilation avec "babel-core/register". En conséquence, l'alias sera également valide pendant les tests.
npm i -D babel-plugin-webpack-aliases
et ajoutez ce paramètre à .babelrc
{
"plugins": [
[ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ]
]
}
La réponse de Danny est géniale. Mais ma situation est un peu différente… .. J'ai utilisé le resolve.alias
de webpack pour utiliser tous les fichiers du dossier src
.
resolve: {
alias: {
'-': path.resolve(__dirname, '../src'),
},
},
et utilisez un préfixe spécial pour mes propres modules, comme ceci:
import App from '-/components/App';
Pour tester un code comme celui-ci, je dois ajouter une commande ln -sf src test/alias/-
avant le test mocha et utiliser l'astuce NODE_PATH=./test/alias
avec laquelle Danny campe. Donc, le script final serait comme ça:
{
"scripts": {
"test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
}
}
PS:
J'ai utilisé -
car de jolis caractères comme @
ou ~
ne sont pas assez sûrs. J'ai trouvé la réponse pour les caractères sécurisés ici
Je pense avoir résolu ce problème. Vous devez utiliser le paquet 2: mock-require et proxyquire.
En supposant que vous ayez un fichier js comme celui-ci:
app.js
import action1 from 'actions/youractions';
export function foo() { console.log(action1()) };
Et votre code de test devrait écrire comme ceci:
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', () => {
...
});
});
arborescence de fichiers
app.js
|- test
|- app.test.js
Commencez par simuler le chemin d'alias en mock-require in before, puis votre objet de test par proxyquire dans beforeEach.
J'ai eu exactement le même problème. Il semble impossible d'utiliser des alias de webpack dans require.js ou dans les nœuds require.
J'ai fini par utiliser mock-require dans les tests unitaires et simplement remplacer les chemins manuellement, comme ceci:
var mock = require('mock-require');
mock('actions/app', '../../src/actions/app');
mock-require est un bon outil car vous voudriez probablement vous moquer de la plupart de vos dépendances au lieu d'utiliser les scripts de src
.
Je suppose que vous auriez --require babel-register
dans votre mocha.opts
. Vous pouvez utiliser le plugin babel module resolver https://github.com/tleunen/babel-plugin-module-resolver Cela vous permet de définir un alias dans .babelrc, similaire à votre alias webpack:
{
"plugins": [
["module-resolver", {
"alias": {
"actions": "./src/actions",
"constants": "./src/constants"
}
}]
]
}
Pour conserver les alias au même endroit, comme config/webpack.common.js
resolve: {
alias: {
'~': path.resolve(__dirname, './../src/app')
}
}
puis installez babel-plugin-webpack-alias
npm i babel-plugin-webpack-alias --save-dev
puis dans .babelrc
mettez:
{
"presets": ["env"],
"plugins": [
["babel-plugin-webpack-alias", {
"config": "./config/webpack.common.js" // path to your webpack config
}]
]
}