If you’re looking for component’s unit tests, check Part 2! ‘Testing Methodologies’ chapter on this page might also be important for your reading.

When building a web-app in Vue or any other JS Framework, it’s important to make sure Vue components work as intended throughout the many iterations a project can have.

Vue.js allows a very easy and ready to go testing setup with Vue Webpack Template, which already includes a boilerplate for unit tests (using Karma and Mocha) and E2E tests (using Nightwatch).

The purpose of this article is to provide different unit test examples on various domains using Karma and Mocha. But first, it’s important to understand some basic JS testing keywords.

Basic Notions

Expect : Used to construct assertions, compare a value with the expected result on a test. Chai Assertions.

: Used to construct assertions, compare a value with the expected result on a test. Chai Assertions. Spy : A test spy is an object that records its interaction with other objects and can be used to check if a certain function was called, the arguments passed to it (if any) and what the return value is (once again, if any). Sinon Spies.

: A test spy is an object that records its interaction with other objects and can be used to check if a certain function was called, the arguments passed to it (if any) and what the return value is (once again, if any). Sinon Spies. Stub : Change how the function is called on the tests. It replaces a function’s behavior, avoiding the original function invocation. Can be used to test how our unit behaves to different return values from a dependency function. Sinon Stubs.

: Change how the function is called on the tests. It replaces a function’s behavior, avoiding the original function invocation. Can be used to test how our unit behaves to different return values from a dependency function. Sinon Stubs. Mount : When mounting a component, an instance is created. The component is rendered as well as its child components.

: When mounting a component, an instance is created. The component is rendered as well as its child components. Shallow: Very similar to mount but child components are stubbed, not rendered or instanced. Very useful in order to reduce the dependencies of a component’s test.

Applying a stub or a spy depends on the test’s context. It relies on how much control is needed to make the testing unit of code isolated from the application’s scope but still achieve the test’s objectives.

You can also find useful resources, people to follow and test libraries on the end of this article.

Testing Methodologies

Writing tests require the developer to understand how the code really works. To understand the deepness of Vue unit testing, it’s required to know what a Vue component instance means and how we can deal with a component’s instance.

Vue components’ attributes are all functions. A component’s beforeMount, mounted (…) are just functions like any other and can be tested like so. When we aim to test a component’s instance, we’re aiming to test Object properties and methods. There’s no black box here, just a behavioral abstraction created by our engine, Vue.

With that in mind, we can approach Vue unit testing in two major ways:

Instance oriented : The component’s instance is created. Big need to control the context as there are some behaviors set by Vue (for example, lifecycle hooks being run). Adding this amount of control will add more code to the test (mocks, stubs, etc, must be created). Code coverage can be influenced by these behaviors as code that is executed on the lifecycle hooks will be marked as covered once it’s executed as the instance is created. The component’s instance behavior will replicate exactly the component’s behavior on the application.

: The component’s instance is created. Big need to control the context as there are some behaviors set by Vue (for example, lifecycle hooks being run). Adding this amount of control will add more code to the test (mocks, stubs, etc, must be created). can be influenced by these behaviors as code that is executed on the lifecycle hooks will be marked as covered once it’s executed as the instance is created. The component’s instance behavior will replicate exactly the component’s behavior on the application. Object oriented: The component’s instance is not created. The context is easier to control as every test unit (a function for example) is tested as an isolated piece of code and doesn’t require such a higher amount of mocking and stubs. Less code is produced to execute the test and code coverage will be more realistic. The component’s behavior can’t be completely reproduced (and it’s not intended to) as the tests will focus on the object’s functions and properties actions. Avoids some annoying errors (as an example, render errors) from underlying dependencies as the instance is not created.

Each methodology has some pros and cons and it’s up to each team or developer to choose. It’s easier to find references to instance oriented tests (as you can see on avoriaz documentation or Vue documentation) but with this article, examples of both approaches will be shown to you!