Search code examples
unit-testingvue.jsvuejs2jestjsvue-test-utils

How to Unit Test a Method in a Vue.js Component using jest


I'm trying to unit test a component method. The question here does not lay out how to access the component method from a unit test.

Specifically, given my Vue component below, how do I access doSomeWork() from my unit test?

Vue component:

<template>
    <div id="ThisStuff">
        <span>
            Some other stuff is going on here
        </span>
    </div>
</template>

<script>
    import foo from 'bar'

    export default {
        props: {
            ObjectWithStuffInIt: [
                {
                    id: 1
                    bar: false
                },
                {
                    id: 2
                    bar: false
                },
            ]
        },
        data: {
            foo: "foo"
        },
        methods: {
            doSomeWork: function() {
                for (var i = 0; i < ObjectWithStuffInIt.length; i++) { 
                    if (foo === "diddly") {
                        ObjectWithStuffInIt[i].bar = true;
                    }
                }
            }
        }
    }
</script>

My test code:

import {createLocalVue, shallow} from 'vue-test-utils'
import ThisVueFile.test.js from '../../thisPlace/ThatPlace/ThisVueFile.vue'
import Vuex from 'vuex'

const localVue = createLocalVue()
localVue.use(Vuex);

describe('ThisVueFile.test.js', () => {
    let user;
    let store;

    beforeEach(() => {
        let getters = {
            user: () => user
        }

        store = new Vuex.Store({ getters })
    })

    // I need to fill propsData: with some local data here 
    //     because it is server data
    // I need to have access to the method
    // I need to use local data for `foo` in the test. 

    it(' When foo is set to -diddly- then set bar to true ', () => {
        foo = "diddly";
        // run the method in the component here 
        doSomeWork();

        expect(OjbectWithStuffInIt[0].bar.equals(true));
    })
})

Solution

  • Calling component method

    The wrapper provides access to the component instance via its vm property, so you could call the method directly with:

    wrapper.vm.doSomeWork()
    

    Setting props

    • The mounting options (passed to shallowMount() or mount()) include the propsData property that could be used to initialize the component's props before mounting.
    • You could also use the wrapper's setProps() after the component has already been mounted.

    Example:

    it('...', () => {
      const wrapper = shallowMount(MyComponent, {
        propsData: {
          myItems: [
            { id: 200, bar: false },
            { id: 300, bar: false }
          ]
        }
      });
    
      // OR
      wrapper.setProps({
        myItems: [
          { id: 400: bar: true }
        ]
      })
    })
    

    Modifying component data property

    • The mounting options includes the data property that could be used to initialize the component's data before mounting.
    • You could also use the wrapper's setData() after the component has already mounted.
    • You could access the component's data property directly through the wrapper's vm property.

    Example:

    it('...', () => {
      const wrapper = shallowMount(MyComponent, {
        data() {
          return {
            foo: 1
          }
        }
      });
    
      // OR
      wrapper.setData({ foo: 2 })
    
      // OR
      wrapper.vm.foo = 3
    })
    

    Full example

    Altogether, your test might look similar to this:

    import { createLocalVue, shallowMount } from '@vue/test-utils'
    import MyComponent from '@/components/MyComponent'
    
    describe('MyComponent', () => {
      it('When foo is set to -something-, set bar to true', () => {
        const myItems = [
          { id: 200, bar: false },
          { id: 300, bar: false }
        ]
        const localVue = createLocalVue()
        const wrapper = shallowMount(MyComponent, {
          localVue,
          propsData: {
            myItems
          }
        })
    
        wrapper.vm.foo = 'something'
        wrapper.vm.doSomeWork()
    
        expect(myItems[0].bar).toBe(true)
      })
    })
    

    demo