使用 Jest 测试 Vue3 组件时如何模拟计算属性

Posted

技术标签:

【中文标题】使用 Jest 测试 Vue3 组件时如何模拟计算属性【英文标题】:How to mock a computed property, when testing a Vue3 component with Jest 【发布时间】:2021-12-24 14:10:16 【问题描述】:

情况

我正在尝试使用 Jest 测试一个简单的 Vue3 组件。我想评估是否呈现了某个文本。该决定取决于一个布尔计算值 (isNeverShowAgain),并且我想模拟该计算值

<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>

如上所示,在现实世界中,这个计算值 (isNeverShowAgain) 取自 vuex 存储属性,这就是我被卡住的地方。有很多帖子展示了如何模拟 vuex 商店,但这对我来说似乎有点过头了。

问题

如何在不模拟完整的 vuex 存储的情况下模拟 isNeverShowAgain 计算值?

上下文

这是我失败的测试:

/**
 * @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');
    );
);

这是我得到的错误:

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 | );

很明显,问题在于未模拟的 vuex 存储,但同样,我如何模拟计算值,这首先取决于存储?

注意事项

请记住,这是 Vue3 和匹配的 Jest2 测试工具,因此一些以前可用的功能现在已弃用,例如 setComputed。

我的依赖

"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",
,

【问题讨论】:

【参考方案1】:

你不必模拟计算,但你必须像这样模拟商店:

const wrapper = mount(WelcomeMessage, 
    $mocks: 
      $store: 
        getters:  
           neverShowWelcomeMessageAgain: true
        
          
    
);

【讨论】:

以上是关于使用 Jest 测试 Vue3 组件时如何模拟计算属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jest 在 Nuxt 中测试组件时如何添加/模拟 Nuxt Auth 库

如何模拟在使用 Jest 测试的 React 组件中进行的 API 调用

Jest、Vue3 和 Typescript:如何通过符号模拟注入?

Vue3 Vite 和 jest 测试没有模板编译器

如何在 React Jest 测试中“模拟”navigator.geolocation

当模拟点击调用调用 promise 的函数时,使用 React 的 Jest 和 Enzyme 进行测试