Chapter 3 – Testing Vue.js Components with Jest

Chapter 3

Test Styles and Structure

So far, we've tested using Jest Snapshots (https://facebook.github.io/jest/docs/snapshot-testing.html). In most cases, that's what we'll use, but sometimes we may want to assert something more specific.

Although you can access a Vue instance via cmp.vm (https://github.com/alexjoverm/vue-testing-series/blob/master/test/MessageList.test.js#L17), you have a set of utilities at your disposal to make it easier. Let's see what we can do.

The Wrapper Object

Wrapper is the main object of vue-test-utils. It is the type returned by the mount, shallowMount, find, and findAll functions. You can see the whole API and typings here (https://github.com/vuejs/vue-test-utils/blob/v1.0.0-beta.27/packages/test-utils/types/index.d.ts).

find and findAll

find and findAll accept a selector (https://github.com/vuejs/vue-test-utils/blob/v1.0.0-beta.27/packages/test-utils/types/index.d.ts#L92) as an argument, which can be a CSS selector and a Vue component as well.

So, we can do things such as:

let cmp = mount(MessageList);

expect(cmp.find(".message").element).toBeInstanceOf(HTMLElement);

// Or even call it multiple times

let el = cmp.find(".message").find("span").element;

// Although for the previous example, we could do it in one

let el = cmp.find(".message span").element;

Asserting Structure and Style

Let's add more tests to MessageList.test.js:

it("is a MessageList component", () => {

  expect(cmp.is(MessageList)).toBe(true);

  // Or with CSS selector

  expect(cmp.is("ul")).toBe(true);

});

it("contains a Message component", () => {

  expect(cmp.contains(Message)).toBe(true);

  // Or with CSS selector

  expect(cmp.contains(".message")).toBe(true);

});

Here, we're using is to assert the root component type and contains to check for the existence of sub-components. Just like find, they receive a Selector, which can be a CSS selector or component.

We have some utils to assert the Vue instance:

it("Both MessageList and Message are vue instances", () => {

  expect(cmp.isVueInstance()).toBe(true);

  expect(cmp.find(Message).isVueInstance()).toBe(true);

});

Now we're going to assert structure in more detail:

it("Message element exists", () => {

  expect(cmp.find(".message").exists()).toBe(true);

});

it("Message is not empty", () => {

  expect(cmp.find(Message).isEmpty()).toBe(false);

});

it('Message has a class attribute set to "message"', () => {

  expect(cmp.find(Message).attributes().class).toBe("message");

});

The exists, isEmpty, and attributes methods come in handy for this.

Then, we have classes and attributes().style to assert styling. Let's update the Message.vue component with a style, since attributes().style asserts only inline styles:

<li style="margin-top: 10px" class="message">{{message}}</li>

Here are the tests:

it("Message component has the .message class", () => {

  expect(cmp.find(Message).classes()).toContain("message");

});

it("Message component has style padding-top: 10", () => {

  expect(cmp.find(Message).attributes().style).toBe("padding-top: 10px;");

});

There is a bunch of utils to make testing Vue components easier. You can find them all in the typings file (https://github.com/vuejs/vue-test-utils/blob/v1.0.0-beta.27/packages/test-utils/types/index.d.ts).

You can find the working code of this chapter on GitHub (https://github.com/alexjoverm/vue-testing-series/blob/Test-Styles-and-Structure-in-Vue-js-and-Jest/test/MessageList.test.js).