简体   繁体   中英

How do I unit test a Vue.js component that relies on a complicated Vuex store and extends another component?

I am wondering how one goes about unit testing a component that uses a complicated Vuex store and extends another component.

Can someone please provide me with an example of how I might go about creating a test that simply asserts that a component that extends another component and relies on Vuex mounts and displays some simple text?

I've tried using vue-test-utils to shallowMount the component under test, but I can't get my test to fail because it has issues even building and mounting the component. As far as I can tell, this is a result of the component leveraging the extended component, and because both components rely on a complicated Vuex store.

Any kind of examples would be appreciated. Thanks.

EDIT:

For further context, our store is broken up into modules. Here is what the store definition file looks like:

/* global phpvars */

import Vue from 'vue'
import Vuex from 'vuex'

import * as actions from './actions'
import * as getters from './getters'
import * as mutations from './mutations'

import acloverrides from '../../modules/acloverrides'
import api from '../../modules/api'
import callback from '../../modules/callback'
import clearlink from '../../modules/clearlink'
import configuration from '../../modules/configuration'
import customer from '../../modules/customer'
import drKeepAlive from '../../modules/drkeepalive'
import interaction from './modules/interaction'
import ivr from './modules/ivr'
import marketing from '../../modules/marketing'
import opportunities from './modules/opportunities'
import order from '../../modules/order'
import orderNotes from './modules/notes'
import products from '../../modules/products'
import sidebar from './modules/sidebar'
import sparks from './modules/sparks'
import training from '../../modules/training'
import transformers from '../../modules/transformers'
import user from '../../modules/user'

let brand = require('../brands/' + phpvars.brand.name + '/modules/brand').default
let forms = require('../brands/' + phpvars.brand.name + '/modules/forms').default

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        acloverrides,
        api,
        brand,
        callback,
        clearlink,
        configuration,
        customer,
        drKeepAlive,
        forms,
        interaction,
        ivr,
        marketing,
        opportunities,
        order,
        orderNotes,
        products,
        sidebar,
        sparks,
        training,
        transformers,
        user
    },
    state: {
        availability: {
            status: false,
            results: {}
        },
        navigation: {
            enabled: phpvars.user.access.order.navigate,
            restrictTo: []
        },
        routes: [],
        router: {},
        editMode: false // Used to determine if the user has clicked the edit button on an existing order.
    },
    actions,
    getters,
    mutations
})

And here is my unit test file:

import Vuex from 'vuex'
import { shallowMount, createLocalVue } from '@vue/test-utils'
import SelectedProducts from '../../resources/assets/js/components/formfields/products/SelectedProducts'
import BaseField from '../../resources/assets/js/components/BaseField'
import store from '../../resources/assets/js/orderform/store/index.js'

const Vue = createLocalVue()
Vue.use(Vuex)

describe('SelectedProducts', () => {
    fit('sanity check', () => {
      window.phpvars = {
        brand: {
          name: 'foobar'
        },
        user: {
          access: {
            order: {
              navigate: true
            }
          }
        }
      }
      const wrapper = shallowMount(SelectedProducts, {
        store: new Vuex.Store(store)
      })
        expect(wrapper.text()).toContain('Selected Products')
    })
})

I find Vue documentation on unit testing to be a bit vague. Give this a shot:

import {createLocalVue, shallowMount} from '@vue/test-utils';
import Vuex from 'vuex';
import store from 'path/to/store/index.js';
import Component from 'path/to/Component';

// create a local instance that uses
// the store, should follow a pattern present
// in your src/main.js
const localVue = createLocalVue();
localVue.use(Vuex);

describe(
  'Component', () => {
    test('renders', () => {
      const wrapper = shallowMount(Component, {
        store: new Vuex.Store(store)
      });
      expect(wrapper.isVueInstance()).toStrictEqual(true);
    });
  }
);

EDIT for your edit

In Jest, window is replaced by global . So you could mock your phpvars with:

global.phpvars = {
    brand: {
      name: 'foobar'
    },
    user: {
      access: {
        order: {
          navigate: true
        }
      }
    }
};

You'll want to place that before you import your store.

Components that extend other components shouldn't be tested any differently, they essentially compile down to a single component in terms of variables and requirements. If you could expand on that question, I'd be happy to answer (like, what issues or errors you are encountering unique to your extended components).

I haven't tested anything I've mentioned so if you do continue to have errors I'll throw together a project. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM