Подтвердить что ты не робот

Использование псевдонимов webpack в тестах мокко

Я разрабатываю веб-приложение для работы в React/Redux/Webpack, и теперь я начинаю интегрировать тестирование с помощью Mocha.

Я следил за инструкциями для написания тестов в документации Redux, но теперь я столкнулся с проблемой с моими псевдонимами 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, здесь script, который я использую в своем package.json.

 {   
   "scripts": {
     "test": "mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
   }
 }

Итак, здесь, где я застреваю. Мне нужно включить псевдонимы из webpack в mocha, когда он работает.

4b9b3361

Ответ 1

Итак, я понял, что все, что я использовал, было в каталоге src/, поэтому мне просто нужно было изменить мой npm run test script.

{   
  "scripts": {
    "test": "NODE_PATH=./src mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
  }
}

Вероятно, это не сработает для всех, но это решило мою проблему.

Ответ 2

Вы также можете использовать плагин babel, который я создал: https://github.com/trayio/babel-plugin-webpack-alias Он преобразует ваш путь с псевдонимом в относительные пути, просто включив плагин babel в ваш .babelrc.

Ответ 3

Думаю, я решил эту проблему. Вы должны использовать 2 пакета: mock-require и 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

Сначала издевайтесь над псевдонимом путем mock-require перед функцией и издевайтесь над вашим тестовым объектом с помощью proxyquire в функции beforeEach.

Ответ 4

Дэнни ответ велик. Но моя ситуация немного другая. Я использовал webpack resolve.alias для использования всех файлов в папке src.

resolve: {
  alias: {
    '-': path.resolve(__dirname, '../src'),
  },
},

и используйте специальный префикс для моих собственных модулей следующим образом:

import App from '-/components/App';

Чтобы протестировать такой код Я должен добавить команду ln -sf src test/alias/- перед мокковым тестом и использовать трюк NODE_PATH=./test/alias Danny camp up with. Итак, окончательный script будет таким:

{   
  "scripts": {
    "test": "ln -sf src test/alias/-; NODE_PATH=./test/alias mocha ./src/**/test/spec.js --compilers js:babel-core/register --recursive"
  }
}

PS:

Я использовал -, потому что красивые символы, такие как @ или ~, недостаточно безопасны. Я нашел ответ для безопасных символов здесь

Ответ 5

Я также столкнулся с той же проблемой, но с этим плагином я решил ее.

https://www.npmjs.com/package/babel-plugin-webpack-aliases

Команда выполнения вашего "мокко" не читает webpack.config.js, поэтому она не может разрешить псевдоним.
Установив этот плагин, рассмотрите webpack.config.js при компиляции с помощью "babel-core/register". В результате псевдоним также будет действовать во время тестирования.

npm i -D babel-plugin-webpack-aliases

и добавьте этот параметр в .babelrc

{
    "plugins": [
        [ "babel-plugin-webpack-aliases", { "config": "./webpack.config.js" } ] 
    ]
}

Ответ 6

У меня была такая же проблема. Кажется невозможным использовать псевдонимы webpack в require.js или в node.

Я закончил использование mock-require в модульных тестах и ​​просто заменил пути вручную, например:

var mock = require('mock-require');

mock('actions/app', '../../src/actions/app');

mock-require - хороший инструмент, потому что, скорее всего, вы хотели бы издеваться над большинством своих зависимостей, а не использовать фактические скрипты из src.