Hybrid Rendering: the secret way to smoothly test Vue.js components

Alex Jover Morales

Alex Jover Morales

Mar 7, 2022
2 min read
Share on Twitter or LinkedIn

In the article Deep vs Shallow Rendering in Vue.js Tests I showed you how deep and shallow rendering works to create Vue.js tests.

Each of them have their own use case and it could depend in your way of testing and architecting as well.

But… why not having the best of both worlds? Let’s get into Hybrid Rendering.

The Hybrid Rendering consists on stubbing only part of the child components on a test.

For instance, taking back the example from the tip, let's add another component called FoodList to the App component:

<template>
  <div>
    <h3>User List</h3>
    <UserList :users="['Rob Wesley']" />
    <FoodList :foods="['Tomatoes', 'Carrots']" />
  </div>
</template>

<script setup>
  import UserList from "./UserList";
  import FoodList from "./FoodList";
</script>

Assuming FoodList has a similar implementation to UserList, and we're using deep rendering, this test:

import { mount } from "@vue/test-utils";
import App from "@/App";

describe("App.vue", () => {
  it("Deep renders the App component", () => {
    const wrapper = mount(App);
    expect(wrapper.html()).toMatchSnapshot();
  });
});

will result in the following snapshot:

<div>
  <h3>User List</h3>
  <ul>
    <li>
      Rob Wesley
    </li>
  </ul>
  <ul>
    <li>
      Tomatoes
    </li>
    <li>
      Carrots
    </li>
  </ul>
</div>

Now, let's say that for whatsoever reason you want only to deep render UserList, but not FoodList.

In that case, you can use the stubs option of the mount method in order to indicate which components must be stubbed:

import { mount } from "@vue/test-utils";
import App from "@/App";

describe("App.vue", () => {
  it("Hybrid renders the app component", () => {
    const wrapper = mount(App, { stubs: ["FoodList"] });
    expect(wrapper.html()).toMatchSnapshot();
  });
});

Notice I'm stubbing FoodList. That's the way to apply hybrid rendering in a test, or partial shallow/deep rendering if you're more comfortable with that name.

The generated snapshot in this case will be like:

<div>
  <h3>User List</h3>
  <ul>
    <li>
      Rob Wesley
    </li>
  </ul>
  <foodlist-stub foods="Tomatoes,Carrots"></foodlist-stub>
</div>

Keep in mind that this won't work with shallowMount, since it already stubs all child components. So make sure to use mount. Learn more in the Stubs and Shallow Mount section on the official docs

Do you have any case in mind where this technique can be useful in your projects? Let me know on Twitter!

That's it for today's tip!

Stay cool 🦄

Don't miss out anything about Vue, your favourite framework.

Subscribe to receive all the articles we publish in a concise format, perfect for busy devs.

Related Articles

Deep vs Shallow Rendering in Vue.js Tests

A short article on how to use deep and shallow rendering in Vue.js and what I suggest to use most of the cases using vue test utils.

Alex Jover Morales

Alex Jover Morales

Mar 3, 2020

Quick Content Testing using Snapshots in Vue.js

Useful tip about how to use snapshot testing in Vue.js the right way and have consistent and coherent tests in your applications

Eduardo San Martín

Eduardo San Martín

May 28, 2019

Testing logic inside a Vue.js watcher

Tutorial on how to test the logic of a vue.js component watcher instead of testing the framework

Javier Martínez

Javier Martínez

Apr 14, 2019

Sponsors

VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.

Silver
Learning Partner