How to test Vue components with Laravel Mix and Mocha
Tags: laravel, php, vue, test
Published: 2019-03-06 15:33:56

---
title: How to test Vue components with Laravel Mix and Mocha
published: true
description: Step by step to setup Vue tests with Laravel and Mocha
tags: laravel, php, vue, test
---

## Introduction
While adding tests to [Laravue](https://github.com/tuandm/laravue), I found that setting unit tests for Vue with Laravel Mix is not simple like [Vue's official document](https://vuejs.org/v2/guide/unit-testing.html). After working around with some google-ing, I've passed the setup steps and just want to share what I've done so far.

## Setup Laravel and npm dependencies
Firstly, we create new Laravel project with [the command](https://laravel.com/docs/5.8/installation#installing-laravel) which every Laravel developer shoud know:

```
composer create-project --prefer-dist laravel/laravel test
cd test
npm install
```
Very easy!

Then we have to setup tests environment as well as required libraries/dependencies. I picked [Mocha + Webpack](https://vue-test-utils.vuejs.org/guides/#testing-single-file-components-with-mocha-webpack) because many articles mentioned this. 

```
npm install --save-dev webpack vue-template-compiler @vue/test-utils mocha mocha-webpack jsdom jsdom-global expect
```
Ok, seems everything is set, let us double check with `npm list --depth=0`

Wow, something is wrong!

```
➜  test npm list --depth=0
...
├── UNMET PEER DEPENDENCY mocha@6.0.2
...
└── UNMET PEER DEPENDENCY webpack@4.29.6

npm ERR! peer dep missing: mocha@>=2.4.5 <=5, required by mocha-webpack@1.1.0
npm ERR! peer dep missing: webpack@^2.0.0 || ^3.0.0, required by mocha-webpack@1.1.0
npm ERR! peer dep missing: webpack@^2.0.0 || ^3.0.0, required by mocha-webpack@1.1.0
```
It says that dependencies' versions are not matched. Seems mocha-webpack is not up-to-date with webpack and mocha, it requires old versions (mocha 2.4.5-5 and webpack 2 or 3 while latest versions are mocha@6 and webpack@2.49.6). Now let's go to the [mocha-webpack](https://github.com/zinserjan/mocha-webpack) repo to see what happens. Indeed, there is no update since last year. Ok, what to do next? We may want to check the issue list to see any similar cases and solutions. Luckily, the [first issue](https://github.com/zinserjan/mocha-webpack/issues/308) is the one we are finding:

```
Hi there, mocha-webpack users!

mocha-webpack has no activity since May, 2018. We at SysGears are maintaining a fork here:
https://github.com/sysgears/mochapack

A new version of mochapack@1.1.0 has been released today with Mocha 6 support.

Check it out!
```

Now we go to [Mochapack](https://github.com/sysgears/mochapack)  as the author recommended, we can see the installation guide for Mochapack:

```
npm install --save-dev mochapack
```
Seems it works. Ok, let's remove the outdated mocha-webpack:
```
npm remove mocha-webpack
```
Wow, `npm list --depth=0` returns very clean result. Don't forget to give the mochapack a star for this awesome work.

## Setup test enviroment
Now we are ready to create test cases for our Vue components following this [guide](https://vue-test-utils.vuejs.org/guides/#testing-single-file-components-with-mocha-webpack). To start it, we have to prepare a environment for tests by creating new folder inside `/tests/`.
```
mkdir tests/js
```
Then create file `setup.js` inside folder `tests/js` and put this line on top:
```
require('jsdom-global')();
```

Next step will be the npm command to run tests, we have to open `package.json` and add this line inside `scripts` section
```
        "test": "mochapack --webpack-config=node_modules/laravel-mix/setup/webpack.config.js --require tests/js/setup.js tests/js/\\*\\*/\\*.spec.js"
```

You can pick any name for `tests/js` folder and `setup.js` file, don't forget to indicate them in the test command

Now is the show time:


```
➜ npm test

 WEBPACK  Compiled successfully in 140ms

 MOCHA  Testing...



  0 passing (0ms)

 MOCHA  Tests completed successfully

```

Wow, it works with 0 test passing - because we haven't added yet. We are going to do it now.

## Writing a test
To save time, we can use `resources/js/components/ExampleComponent.vue` of Laravel to write test. If you take a look to this component, you will see it just shows the `Example Component` header. Now we create a test file `tests/js/components/ExampleComponent.spec.js` and put these lines to that file
```
// tests/js/components/ExampleComponent.spec.js
import { mount } from '@vue/test-utils';
import expect from 'expect';
import ExampleComponent from '../../../resources/js/components/ExampleComponent.vue';

describe('ExampleComponent.vue', () => {
  it('says that it is an example component', () => {
    const wrapper = mount(ExampleComponent);
    expect(wrapper.html()).toContain('Example Component');
  });
});
```
This test case is to check after ExampleComponent mounted, `Example Component` should be in the output html.

Save the file and run the test command again:

```
➜ npm test
 WEBPACK  Failed to compile with 1 error(s)

Error in ./resources/js/components/ExampleComponent.vue?vue&type=template&id=299e239e&

  Module build failed (from ./node_modules/vue-loader/lib/loaders/templateLoader.js):
  TypeError: Super expression must either be null or a function
      at /.../test/node_modules/prettier/index.js:40358:5
      at /.../test/node_modules/prettier/index.js:40378:4

npm ERR! Test failed.  See above for more details.
```
Ok, we've got the error. You will be crazy to find out the answer for this error from internet. Don't worry, just do this fix: Open `tests/js/setup.js` again and put this line next to the first one:

```
window.Date = Date;
```

Save `setup.js` file and run test command again

```
➜ npm test

 WEBPACK  Compiled successfully in 1436ms

 MOCHA  Testing...



  ExampleComponent.vue
Component mounted.
    ✓ says that it is an example component


  1 passing (22ms)

 MOCHA  Tests completed successfully
```
Yeah, it works, test case passed. Now we can put more Vue components and tests them.

Please enjoy testing! You can find my sample here: https://github.com/tuandm/laravel-vue-tests-with-mocha

Noted: I'm using MacOS Mojave 10.14.2, all related tools (npm, composer...) are considered as last versions.