Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a computed property, when testing a Vue3 component with Jest

Situation

I am trying to test a simple Vue3 component with Jest. I want to evaluate whether a certain text is rendered. The decision is dependent on a boolean computed value (isNeverShowAgain), and I want to mock that computed value.

<template>
    <div :class="{ modal: true, 'is-active': showDialog }">
    ....
                <WelcomeText />
    ....
    </div>
</template>
<script lang="ts">
    ....
export default defineComponent({
    name: 'WelcomeMessage',
    components: { WelcomeText },
    data() {
        return {
            /** Whether to show the message this time*/
            showDialog: false,
    ....
        };
    },
    beforeMount() {
        //Decide whether to actually show this dialog now, before mounting it, to avoid any flicker
        this.showDialog = !this.isNeverShowAgain === true;
    },
    ....
    computed: {
        /** Whether the welcome message has been permanently dismissed */
        isNeverShowAgain(): boolean {
            return this.$store.getters.neverShowWelcomeMessageAgain;
        },
    },
});
</script>

Like shown above, in the real world this computed value (isNeverShowAgain) is taken from a vuex store property, and this is where I am stuck. There are many posts that show how to mock the vuex store, but this seems overkill to me.

Question

How can I mock the isNeverShowAgain computed value, without mocking the complete vuex store?

Context

Here is my failing test:

/**
 * @jest-environment jsdom
 * @devdoc See https://github.com/vuejs/vue-test-utils-next/issues/194#issue-689186727 about the setup with "as any"
 */

import { mount } from '@vue/test-utils';
import WelcomeMessage from '@/components/WelcomeMessage.vue';

describe('WelcomeMessage.vue', () => {
    it('should display the message', () => {
        const wrapper = mount(WelcomeMessage, {
            computed: {
                isNeverShowAgain() {
                    return false;
                },
            },
        } as any);
        // wrapper.vm.setComputed({ isNeverShowAgain: false }); //Deprecated and does not work

        // Assert the rendered text of the component
        expect(wrapper.text()).toContain('Welcome');
    });
});

Here is the error I get:

TypeError: Cannot read property 'getters' of undefined

  69 |         /** Whether the welcome message has been permanently dismissed */
  70 |         isNeverShowAgain(): boolean {
> 71 |             return this.$store.getters.neverShowWelcomeMessageAgain;
     |                                ^
  72 |         },
  73 |     },
  74 | });

It's obvious that the problem is a not mocked vuex store, but again, how can I mock the computed value, that depends on the store in the first place?

Notes

Remember, this is Vue3 and the matching Jest2 test utils, so some previously available features are now deprecated like setComputed.

My dependencies

"devDependencies": {
    .....
    "@types/jest": "^27.0.2",
    "@vue/test-utils": "^2.0.0-rc.16",
    "@vue/vue3-jest": "^27.0.0-alpha.3",
    "jest": "^27.3.1",
    "jest-cli": "^27.3.1",
    "ts-jest": "^27.0.7",
    "ts-node": "^10.4.0",
    "typescript": "~4.1.5",
},
like image 874
Marcel Avatar asked Oct 14 '25 08:10

Marcel


1 Answers

You don't have to mock the computed but you have to mock the store like this:

const wrapper = mount(WelcomeMessage, {
    $mocks: {
      $store: {
        getters: { 
           neverShowWelcomeMessageAgain: true
        }
      }    
    }
});
like image 129
Adri HM Avatar answered Oct 17 '25 21:10

Adri HM