首页 > 解决方案 > 在笑话包装器中模拟 beforeMount

问题描述

我目前正在尝试用 Jest 测试我的 vue 组件。我的 index.vue 文件中有一个 beforeMount 挂钩,看起来像这样

beforeMount() {
    this.ProjectName = this.$route.query.ProjectName
    this.loadOutputs()
}

使用方法 loadOutputs()

loadOutputs() {
    this.Project.name
    const path = 'http://localhost:5000/loadoutputs'
      axios
        .post(path)
        .then((res) => {
        this.Results = res.data
        })
}

我正在尝试编写测试,但我找不到如何在包装器中模拟 beforeMount 钩子

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

import My_Page from '@/views/test/index'
import ProjectInputs from '../json/Project_inputs.json'
import ProjectStatusInputs from '../json/Project_status.json'
import Project_Results from '../json/Project.json'

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

jest.mock('axios')

describe('My_Page', () => {
    const localVue = createLocalVue()
    localVue.use(Vuex)
    localVue.use(ElementUI)
    let My_PageId = 1

    const $router = {
        push: jest.fn(),
    }

    let store = new Vuex.Store({
        state: {
            Project: ProjectInputs,
            ProjectStatus: ProjectStatusInputs
        }
    })
    
    const wrapper = shallowMount(My_Page, {
        localVue,
        store,
        mocks: {
            $router,
            $route: {
                params: {
                    My_PageId : My_PageId ,
                },
                query: {
                    ProjectName: 'Name'
                }
            }
        }
    })

它总是给我同样的错误

无法读取未定义的属性“变量”

因为它不会模拟 Results 变量。我在 Project_Results 中有一个 Results 变量的示例,但我不知道如何将它放入我的包装器中。

任何想法?

标签: unit-testingvue.jsjestjs

解决方案


你是在正确的方式。您已经用 jest 定义了 axios 模拟模块。您只需要定义模拟的行为。您想要的行为是:当 axios.post 被调用时,使用特定的响应数据解决它。(参考

我以您的代码为例创建了一个简单的组件和测试规范。

// @file ViewTest.vue
<template>
  <div></div>
</template>

<script>
import axios from 'axios';

export default {
  beforeMount() {
    this.ProjectName = this.$route.query.ProjectName;
    this.loadOutputs();
  },
  methods: {
    loadOutputs() {
      const path = 'http://localhost:5000/loadoutputs';
      axios.post(path).then((res) => {
        // Notes:
        // - set Results is inside then method (resolve condition).
        // - Results get only property data from res.
        this.Results = res.data;
      });
    },
  },
};
</script>

规格文件

// @file: 64753951.spec.js
import { shallowMount } from '@vue/test-utils';
import SimpleComponent from '@/components/SimpleComponent.vue';
import axios from 'axios';

jest.mock('axios');

describe('SimpleComponent', () => {
  // Use async here.
  it('beforeMount check', async () => {
    // Put axios.post result here.
    const fakeResult = { data: 'xxx' };
    // Define mock axios post here.
    axios.post.mockResolvedValue(fakeResult);

    // Note: need to await for beforeMount to finish.
    const wrapper = await shallowMount(SimpleComponent, {
      mocks: {
        $route: {
          query: {
            ProjectName: 'Name',
          },
        },
      },
    });

    // Check whether ProjectName set correctly from mocks.$route.query.
    expect(wrapper.vm.ProjectName).toEqual('Name');
    // Check whether property Results set correctly from mock axios resolve value.
    expect(wrapper.vm.Results).toEqual(fakeResult.data);
  });
});

然后我从终端运行它

$ npx jest test/64753951.spec.js
 PASS  test/64753951.spec.js
  SimpleComponent
    ✓ beforeMount check (7 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.377 s

推荐阅读