web-dev-qa-db-fra.com

Utilisation d'alias de webpack dans les tests mocha

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. 

47
Danny Delott

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.

37
Danny Delott

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.

14
adriantoine

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" } ] 
    ]
}
4
Yuki Hirano

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

3
Stupidism

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.

2
zhaozhiming

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.

1
Ilya Kogan

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"
       }
    }]
  ]
}
1
Northern

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
        }]
    ]
}
0
ScorpAL