Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a Vue page like this:

<template>
</template>

<script>
created(){
    this.doSomething();
}

methods: {
    doSomething() {
        .....
    }
}

</script>

Now, we want to the testing of this created hook and check that doSomething() method is called.

Tried like this, jest is also imported in package.json

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

const localVue = createLocalVue();

import Xyx from '/Xyx.vue';

const init = () => {
  wrapper = shallowMount(Xyx, { localVue });
  cmp = wrapper.vm;
};

describe('#created', () => {
  it('#doSomething', () => {
    init();
    wrapper.setMethods({
      doSomething: jest.fn(),
    })
    expect(cmp.doSomething).toHaveBeenCalled();
  });
});

Can I do the unit test case of this created hook?

like image 724
Neeladri Rudra Avatar asked May 09 '19 06:05

Neeladri Rudra


2 Answers

The methods option was deprecated in v1 of @vue/test-utils, so the accepted answer no longer works. I ran into this issue myself and decided to dig into the source to figure out how I could test this.

It looks like Vue actually stores all the hooks in the $options property. Each hook has an option that is an array of functions. It is important to note that a context is not bound to said functions, so you will need to use call or apply to execute them.

vm.$options.created.forEach(hook => {
  hook.call(vm);
});
like image 140
callmehiphop Avatar answered Oct 21 '22 07:10

callmehiphop


Because your method is called on created, it is run before you are setting the mock. Therefore, your test will fail.
You have to replace the method with the mock on initialization (in your case, on shallowMount):

describe('Xyz', () => {
  it('should call doSomething() when created', () => {
    const doSomething = jest.fn()
    wrapper = shallowMount(Xyz, {
      localvue,
      methods: { doSomething }
    });
    expect(doSomething).toHaveBeenCalled();
  });
});

Sidenote: you're not declaring cmp. At the start of your test, you should have a let cmp;


A very similar discussion here. Above the linked comment there's a method to mock properties of most Vue component lifecycle hooks.

like image 37
tao Avatar answered Oct 21 '22 08:10

tao