Skip to content

Commit c73c21d

Browse files
committed
docs: update mocha-webpack SFC guide
1 parent f68e1ed commit c73c21d

File tree

2 files changed

+83
-50
lines changed

2 files changed

+83
-50
lines changed

docs/en/guides/testing-SFCs-with-jest.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Testing single file components with Jest
1+
# Testing Single File Components with Jest
22

33
> An example project for this setup is available on [GitHub](https://github.com/vuejs/vue-test-utils-jest-example).
44
@@ -54,7 +54,7 @@ Next, create a `jest` block in `package.json`:
5454
}
5555
```
5656

57-
> **Note:** `jest-vue` currently does not support all the features of `vue-loader`, for example custom block support and style loading. To use them, read the guide on [testing SFCs with Mocha + webpack](./testing-SFCs-with-mocha-webpack.md).
57+
> **Note:** `jest-vue` currently does not support all the features of `vue-loader`, for example custom block support and style loading. In addition, some webpack-specific features such as code-splitting are not supported either. To use them, read the guide on [testing SFCs with Mocha + webpack](./testing-SFCs-with-mocha-webpack.md).
5858
5959
## Handling webpack Aliases
6060

Original file line numberDiff line numberDiff line change
@@ -1,83 +1,118 @@
1-
# Testing single file components with Mocha + webpack
1+
# Testing Single File Components with Mocha + webpack
22

3-
We need to compile single file components (SFCs) to run them in Mocha.
3+
Another strategy for testing SFCs is compiling all our tests via webpack and then run it in a test runner. The advantage of this approach is that it gives us full support for all webpack and `vue-loader` features, so we don't have to make compromises in our source code.
44

5-
We can make use of a package called `mocha-webpack`, that does exactly that. It compiles source files in webpack before running Mocha.
5+
You can technically use any test runner you like and manually wire things together, but we've found [`mocha-webpack`](https://github.com/zinserjan/mocha-webpack) to provide a very streamlined experience for this particular task.
66

7-
## Setting up mocha-webpack
7+
## Setting Up `mocha-webpack`
88

9-
The first thing to do is install Mocha, mocha webpack, webpack and webpack loaders:
9+
We will assume you are starting with a setup that already has webpack, vue-loader and Babel properly configured - e.g. the `webpack-simple` template scaffolded by `vue-cli`.
10+
11+
The first thing to do is installing test dependencies:
1012

1113
```bash
12-
npm install --save-dev vue-test-utils mocha mocha-webpack webpack webpack-node-externals vue vue-loader css-loader babel-loader
14+
npm install --save-dev vue-test-utils mocha mocha-webpack
1315
```
1416

15-
Next we need to define a unit script in our `package.json`.
17+
Next we need to define a test script in our `package.json`.
1618

1719
```json
1820
// package.json
1921
{
2022
"scripts": {
21-
"unit": "mocha-webpack --webpack-config build/webpack.conf.js test --recursive --require test/setup.js"
23+
"test": "mocha-webpack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
2224
}
2325
}
2426
```
2527

26-
This script tells `mocha-webpack` to get the webpack config from `build/webpack.conf.js`, run all test files in the test directory and run `test/setup.js` before the tests.
28+
A few things to note here:
2729

28-
### Setting Up Browser Environment
30+
- The `--webpack-config` flag specifies the webpack config file to use for the tests. In most cases, this would be identical to the config you use for the actual project with one small tweak. We will talk about this later.
31+
32+
- The `--require` flag ensures the file `test/setup.js` is run before any tests, in which we can setup the global environment for our tests to be run in.
33+
34+
- The final argument is a glob for the test files to be included in the test bundle.
35+
36+
### Extra webpack Configuration
37+
38+
#### Externalizing NPM Dependencies
39+
40+
In our tests we will likely import a number of NPM dependencies - some of these modules may be written without browser usage in mind and simply cannot be bundled properly by webpack. Another consideration is externalizing dependencies greatly improves test boot up speed. We can externalize all NPM dependencies with `webpack-node-externals`:
41+
42+
```js
43+
// webpack.config.js
44+
const nodeExternals = require('webpack-node-externals')
45+
46+
module.exports = {
47+
// ...
48+
externals: [nodeExternals()]
49+
}
50+
```
51+
52+
#### Source Maps
53+
54+
Source maps need to be inlined to be picked up by `mocha-webpack`. The recommended config is:
55+
56+
``` js
57+
module.exports = {
58+
// ...
59+
devtool: "inline-cheap-module-source-map"
60+
}
61+
```
2962

30-
Let's create the setup.js script first.
63+
If debugging via IDE, it's also recommended to add the following:
3164

32-
`vue-test-utils` requires a browser environment to run. We can set one up using `jsdom-global`, which setups a JSDOM instance and attaches necessary globals to the Node process.
65+
``` js
66+
module.exports = {
67+
// ...
68+
output: {
69+
// ...
70+
// use absolute paths in sourcemaps (important for debugging via IDE)
71+
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
72+
devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
73+
}
74+
}
75+
```
3376

34-
Let's install the dependencies:
77+
### Setting Up Browser Environment
78+
79+
`vue-test-utils` requires a browser environment to run. We can simulate it in Node.js using `jsdom-global`:
3580

3681
```bash
3782
npm install --save-dev jsdom jsdom-global
3883
```
3984

40-
Create a `test/setup.js` file and paste the following code in:
85+
Then in `test/setup.js`:
4186

4287
``` js
4388
require('jsdom-global')()
4489
```
4590

4691
This adds a browser environment to node, so that `vue-test-utils` can run correctly.
4792

48-
### Configuring webpack
93+
### Picking an Assertion Library
4994

50-
Now we need to create a webpack config file. In most cases your test config should use the same `module` rules with your projects existing webpack config. We recommend extracting the common config options into a base file and extend it separately for build and testing.
95+
[Chai](http://chaijs.com/) is a popular assertion library that is commonly used alongside Mocha. You may also want to check out [Sinon](http://sinonjs.org/) for creating spies and stubs.
5196

52-
One specific tweak needed for the test config is that we should externalize Node dependencies with `webpack-node-externals`. This significantly speeds up the bundling process.
97+
Alternatively you can use `expect` which is now part of Jest, and exposes [the exact same API](http://facebook.github.io/jest/docs/en/expect.html#content) in Jest docs.
5398

54-
For our example project, the config looks like this:
99+
We will be using `expect` here and make it globally available so that we don't have to import it in every test:
55100

56-
```js
57-
const nodeExternals = require('webpack-node-externals')
101+
``` bash
102+
npm install --save-dev expect
103+
```
58104

59-
module.exports = {
60-
module: {
61-
rules: [
62-
{
63-
test: /\.vue$/,
64-
loader: 'vue-loader'
65-
},
66-
{
67-
test: /\.js$/,
68-
loader: 'babel-loader',
69-
exclude: /node_modules/
70-
}
71-
]
72-
},
73-
externals: [nodeExternals()],
74-
devtool: '#eval-source-map'
75-
}
105+
Then in `test/setup.js`:
106+
107+
``` js
108+
require('jsdom-global')()
109+
110+
global.expect = require('expect')
76111
```
77112

78-
### Configuring Babel
113+
### Optimizing Babel for Tests
79114

80-
Notice that we are using `babel-loader` to handle JavaScript. You should already have Babel configured if you are using it in your app, e.g. via a `.babelrc` file. Here `babel-loader` will automatically use the same config file.
115+
Notice that we are using `babel-loader` to handle JavaScript. You should already have Babel configured if you are using it in your app via a `.babelrc` file. Here `babel-loader` will automatically use the same config file.
81116

82117
One thing to note is that if you are using Node 6+, which already supports the majority of ES2015 features, you can configure a separate Babel [env option](https://babeljs.io/docs/usage/babelrc/#env-option) that only transpiles features that are not already supported in the Node version you are using (e.g. `stage-2` or flow syntax support, etc.)
83118

@@ -114,24 +149,17 @@ And create a test file named `test/Counter.spec.js` with the following code:
114149

115150
```js
116151
import { shallow } from 'vue-test-utils'
117-
import { expect } from 'chai'
118152
import Counter from '../src/Counter.vue'
119153

120154
describe('Counter.vue', () => {
121155
it('increments count when button is clicked', () => {
122156
const wrapper = shallow(Counter)
123157
wrapper.find('button').trigger('click')
124-
expect(wrapper.find('div').text()).to.contain('1')
158+
expect(wrapper.find('div').text()).toMatch('1')
125159
})
126160
})
127161
```
128162

129-
Notice we're using `expect` from `chai` to make our assertion. We need to install chai before running the tests:
130-
131-
```
132-
npm install --save-dev chai
133-
```
134-
135163
And now we can run the test:
136164

137165
```
@@ -142,4 +170,9 @@ Woohoo, we got our tests running!
142170

143171
### Resources
144172

145-
- [Example project using mocha-webpack](https://github.com/eddyerburgh/vue-test-utils-mocha-example)
173+
- [Example project for this setup](https://github.com/vuejs/vue-test-utils-mocha-webpack-example)
174+
- [Mocha](https://mochajs.org/)
175+
- [mocha-webpack](http://zinserjan.github.io/mocha-webpack/)
176+
- [Chai](http://chaijs.com/)
177+
- [Sinon](http://sinonjs.org/)
178+
- [jest/expect](http://facebook.github.io/jest/docs/en/expect.html#content)

0 commit comments

Comments
 (0)