Jay Dadhaniya
Jay Dadhaniya

Reputation: 199

Testing with `Updated` hook with `vue-test-utils` and `jest`

I have vue component code like below

updated: function() {
   // set showPackages = true after all the child component render
   this.$nextTick(function() {
      this.show = this.element.show ? true : false
      this.done = true
   })
}

Now, we want to the testing of this updated hook and check that this.show is set or not.

Does anyone have any idea how to write test cases for this lifecycle hook?

Upvotes: 3

Views: 3110

Answers (3)

Jean Grimbert
Jean Grimbert

Reputation: 51

The easiest way seems to setProps, has the parent would do

it('When parent's index change, call the updateHandler', () => {
   const wrapper = mount(YourComponent, { localVue });
   const spy = jest.spyOn(wrapper.vm, 'handleUpdate');
   wrapper.setProps({ index : 1 });
   expect(spy).toHaveBeenCalled()
})

Upvotes: 2

Alonad
Alonad

Reputation: 2236

Updated hook fires when route changes, so what we need to do is to change route.

Add router to test

import { shallowMount, config, createLocalVue } from "@vue/test-utils";
import VueRouter from "vue-router";
const localVue = createLocalVue();
localVue.use(VueRouter);

Initiate it and add to wrapper

const router = new VueRouter({
  mode: "abstract"
});
const wrapper = shallowMount(YourComponent, {
  localVue,
  router
};

And then push new route during test

router.push('/route-1');

This will trigger updated hook

Upvotes: 1

Simon Thiel
Simon Thiel

Reputation: 3285

You would extract the logic of your update hook to a separate method:

  updated() {
    // set showPackages = true after all the child component render
    this.handleUpdate();
  },

  methods: {
    handleUpdate() {
      this.$nextTick(() => {
        this.show = this.element.show ? true : false;
        this.done = true;
      });
    }
  }

The unit test:

import { createLocalVue, shallowMount } from '@vue/test-utils';
import YourComponent from '@/components/YourComponent';

const localVue = createLocalVue();

describe('YourComponent.vue', () => {

  test('async update lifecycle hook behavior', () => {
    const wrapper = shallowMount(YourComponent, {
      localVue,
      propsData: {
        element: {
          show: false
        },
        done: false,
        show: true
      }
    });
    expect(wrapper.exists()).toBe(true);
    expect(wrapper.vm.done).toBe(false);
    wrapper.vm.handleUpdate();
    wrapper.vm.$nextTick(() => {
      expect(wrapper.vm.done).toBe(true);
      expect(wrapper.vm.show).toBe(false);
    });
  });
});

See also: https://vue-test-utils.vuejs.org/guides/testing-async-components.html

Additional suggestion:

You can further improve your code by replacing:

this.show = this.element.show ? true : false;

by

this.show = !!this.element.show;

(see also: https://eslint.org/docs/rules/no-unneeded-ternary)

Upvotes: 2

Related Questions