vuejs-templates / webpack

A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.
MIT License
9.7k stars 4.39k forks source link

feature request: add chai-as-promised to dev-dependency #646

Closed alexey2baranov closed 6 years ago

alexey2baranov commented 7 years ago

Hello! I think many of us or totally every of us use promises in their code. So karma-chai-as-promised configured would be very good.

the main use case with chai-as-promised is testing async methods which should rejected

expect(models.Golos.get(3)).eventually.rejectedWith(ArgumentError, /invalid args count/i)

thanks!

aldencolerain commented 7 years ago

I was able to get this to work, but it took some time sifting through all of them comments and incompatibilities.

Install: npm install chai-as-promised --save-dev

To use in my test added at the top:

const expect = require('chai').use(require('chai-as-promised')).expect;

And in my test case:

expect(promisefunc()).to.eventually.equal(123);

karma.conf.js: added:

  [require.resolve('chai-as-promised')]: ['webpack'],

complete file:


var webpackConfig = require('../../build/webpack.test.conf');

module.exports = function (config) {
  config.set({
    browsers: ['PhantomJS'],
    frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
    reporters: ['spec', 'coverage'],
    files: ['../../node_modules/babel-polyfill/dist/polyfill.js',
            './index.js'],
    preprocessors: {
      './index.js': ['webpack', 'sourcemap'],
      [require.resolve('chai-as-promised')]: ['webpack'],
    },
    webpack: webpackConfig,
    webpackMiddleware: {
      noInfo: true,
    },
    coverageReporter: {
      dir: './coverage',
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' },
      ]
    },
  });
};

webpack.test.conf.js changed:

rules: utils.styleLoaders().concat([
      {
        test: require.resolve('chai-as-promised'),
        use: 'babel-loader'
      }
    ])

complete file:

// This is the webpack config used for unit tests.

var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseConfig = require('./webpack.base.conf')

var webpackConfig = merge(baseConfig, {
  // use inline sourcemap for karma-sourcemap-loader
  module: {
    rules: utils.styleLoaders().concat([
      {
        test: require.resolve('chai-as-promised'),
        use: 'babel-loader'
      }
    ])
  },
  devtool: '#inline-source-map',
  resolveLoader: {
    alias: {
      // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
      // see discussion at https://github.com/vuejs/vue-loader/issues/724
      'scss-loader': 'sass-loader'
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/test.env')
    })
  ]
})

// no need for app entry during tests
delete webpackConfig.entry

module.exports = webpackConfig
DRL9 commented 7 years ago

@aldencolerain Hello! I can't get your method to work. I init a empty vuejs-template/webpack project, and I change the config like you. However, the test result isn't as expected. Here is my test code:

const expect = require('chai').use(require('chai-as-promised')).expect;

describe('Test', () => {
  it('test', () => {
    //should failed
    expect(Promise.resolve(1111)).to.eventually.equal(123);
  })
})

When I run npm run unit, the test pass successfully.

aldencolerain commented 6 years ago

@DRL9 I'm not exactly sure why your example isn't working, I eventually found that using async/await was significantly easier and less difficult than using chai-as-expected. I just created a utility function to handle checking rejected promise errors. Here are some examples from my code:

it('should return an empty object if we got a good response with no payload', async function() {
  expect(await request('GET', '/')).to.deep.equal({});
});

it('should throw api request error with empty fields and alert user on a network error', async function() {
  const error = await rejection(() => request('GET', '/'));
  expect(error).to.be.instanceof(Error);
  expect(error.message).to.equal('API Request Error');
});

Here is my utility function for checking rejected promises:

async function rejection(func) {
  try {
    await func();
  } catch (error) {
    return error;
  }
  return null;
}
LinusBorg commented 6 years ago

Since we will shortly switch to Jest (#817), this is soon obsolete.