DEV Community

Alex Jover
Alex Jover

Posted on β€’ Originally published at vuedose.tips on

3 2

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

Originally posted on VueDose.tips

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>
Enter fullscreen mode Exit fullscreen mode

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();
  });
});
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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();
  });
});

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

Keep in mind that this won't work with shallowMount, since it already stubs all child components. So make sure to use mount.

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 πŸ¦„

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

πŸ‘‹ Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay