javascript - jest mock vuex useStore() med vue 3 composition api


Jag försöker enhetstesta en komponent där du klickar på en knapp som då ska anropa store.dispatch('favoritesState/deleteFavorite').

Denna åtgärd anropar sedan ett API och gör sitt arbete. Jag vill inte testa implementationen av vuex-butiken, bara att vuex-åtgärden anropas när du klickar på knappen i komponenten.

Komponenten ser ut så här

<template>
    <ion-item :id="favorite.key">
        <ion-thumbnail class="clickable-item remove-favorite-item" @click="removeFavorite()" slot="end" id="favorite-star-thumbnail">           
        </ion-thumbnail>
    </ion-item>
</template>

import {useStore} from "@/store";
export default defineComponent({
     setup(props) {
        const store = useStore();
    
        function removeFavorite() {
            store.dispatch("favoritesState/deleteFavorite", props.item.id);
        }

        return {
            removeFavorite,
        }
     }
});

Jest-testet

import {store} from "@/store";

test(`${index}) Test remove favorite for : ${mockItemObj.kind}`, async () => {

    const wrapper = mount(FavoriteItem, {
        propsData: {
            favorite: mockItemObj
        },
        global: {
            plugins: [store]
        }
    });
    const spyDispatch = jest.spyOn(store, 'dispatch').mockImplementation();

    await wrapper.find('.remove-favorite-item').trigger('click');
    expect(spyDispatch).toHaveBeenCalledTimes(1);
});

Jag har försökt med olika lösningar med samma resultat. När "trigger('click')" körs kastas detta fel:

Kan inte läsa egenskaper av undefined (läser 'dispatch') TypeError: Kan inte läsa egenskaper av undefined (läser 'dispatch')

Projektet är skrivet i vue3 med typescript och använder composition API och vuex4

Svar #1

Jag hittade en lösning på mitt problem. Detta är lösningen jag slutade med.

favorite.spec.ts

import {key} from '@/store';

let storeMock: any;

beforeEach(async () => {
    storeMock = createStore({});
});

test(`Should remove favorite`, async () => {

        const wrapper = mount(Component, {
            propsData: {
                item: mockItemObj
            },
            global: {
                plugins: [[storeMock, key]],
            }
        });
        const spyDispatch = jest.spyOn(storeMock, 'dispatch').mockImplementation();

        await wrapper.find('.remove-favorite-item').trigger('click');
        expect(spyDispatch).toHaveBeenCalledTimes(1);
        expect(spyDispatch).toHaveBeenCalledWith("favoritesState/deleteFavorite", favoriteId);
    });

Detta är komponentmetoden:

  setup(props) {
    const store = useStore();
   
    function removeFavorite() {
        store.dispatch("favoritesState/deleteFavorite", favoriteId);
    }

    return {
        removeFavorite
    }
  }