Тестирование компонентов Vue - состояние и методы имитации

Я пытался разобраться в модульном тестировании компонентов Vue, но, похоже, не совсем понимаю, как имитировать / заглушать объекты и методы хранилища, которые вызывают асинхронный API.

Это пример компонента Vue, который у нас есть:

import { mapState, mapGetters } from 'vuex'
import router from 'components/admin/router'

export default {
name: 'Users',
computed: {
    ...mapState('admin', [
        'users',
    ]),
    ...mapGetters({
        requestInProgress: 'requestInProgress',
    }),
},
data: function() {
    return {
        filterTerm: '',
        usersLoaded: false,
    }
},
methods: {        
    getUsers(filter) {
            this.$store.dispatch('admin/getUserList', filter)
                .then(res => {
                    this.usersLoaded = true
                })
                .catch(e => {
                    this.$toast.error({
                        title: 'Failed to retrieve data',
                        message: this.$options.filters.normaliseError(e),
                    })
                })            
    },
},
mounted() {
    this.getUsers('*')
},

}

И это тест, который я хочу написать. Я даже не могу заставить тест работать чисто, на самом деле не пытаясь что-либо утверждать

import Vue from 'vue'
import { shallowMount } from '@vue/test-utils'
import Users from 'components/admin/pages/user/users.vue'

describe('Users Vue', () => {
    it('Page Should Load', () => {
     const mockResponse = {
          data: [{
            "id": "1",
            "emailAddress": "[email protected]",
            "firstName": "Luke",
            "lastName": "Niland",
            "staffNumber": "12345",
            "phoneNumber": "07707 999999",
            "active": true
        }
    ]};

    let actions
    let store

    beforeEach(() => {
        actions = {
            'admin/getUserList': sinon.stub()                      
                  .returns(Promise.resolve(mockResponse))
        }
        store = new Vuex.Store({
            state: {},
            actions
        })
    })                   

    const wrapper = shallowMount(Users, { store })

    const h5 = wrapper.find('h5')
    expect(h5.text()).toBe('User Administration')  
  })
 })

Ошибки, которые я обычно возвращаю, связаны с неопределенными элементами, обычно в этом случае $store.dispatch равно undefined. Я чувствую, что где-то упускаю что-то с насмешкой, или тот факт, что getUsers(), вызываемый на монтировке, сбивает его с толку.


person beakersoft    schedule 01.10.2018    source источник
comment
кто называет filterUsers? может быть, этот контекст filterUsers неверен?   -  person Walker Leite    schedule 10.01.2019
comment
Ошибка копирования и вставки кода, он вызывается при монтировании компонента. Обновил код   -  person beakersoft    schedule 10.01.2019
comment
Использовали ли вы в своих тестах экземпляр localVue? Полагаю, без него ваш макет не будет ни к чему привязан. См. здесь.   -  person P3trur0    schedule 10.01.2019


Ответы (2)


Чтобы протестировать компонент Vue, имитирующий Vuex, как вы это делаете в своем примере, можно передать фиктивный store в Vue, когда вы shallowMount свой компонент в процессе, поэтому:

shallowMount(Users, { store })

но этот макет store необходимо также подключить к базовому конструктору Vue. Для этого вы должны передать его - localVue. localVue - это конструктор Vue с ограниченной областью видимости, в который вы можете вносить изменения в области тестирования, не затрагивая глобальный конструктор Vue, фактически используемый в вашем приложении.

Более того, в вашем конкретном случае вы не импортировали и не устанавливали Vuex.

Затем для правильной настройки теста вам необходимо:

  1. создайте экземпляр localVue, вызвав функцию createLocalVue служебной программы Vue Test Utils, и установите на него Vuex:
    import { shallowMount, createLocalVue } from '@vue/test-utils'
    import Vuex from 'vuex'

    //creating the local Vue instance for testing
    const localVue = createLocalVue()

    //mounting Vuex to it
    localVue.use(Vuex)
  1. Изменение вашей shallowMount функции, добавив также экземпляр localVue к полезной нагрузке:
 const wrapper = shallowMount(Users, { store, localVue })

Ссылки на официальную документацию см. здесь.

Еще один полезный ресурс о тестировании Vue - это эта книга (для вашего конкретного случая см. главу 7) и его репозиторий GitHub

person P3trur0    schedule 11.01.2019

Вы должны создать локальный Vue для своих тестов и установить плагин Vuex:

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

const localVue = createLocalVue()

localVue.use(Vuex)

const wrapper = shallowMount(...)

person Walker Leite    schedule 10.01.2019