簡體   English   中英

如何在vue3組件測試中修改pinia中state的值並影響組件?

[英]How can I modify the value of state in pinia in vue3 component test and affect the component?

使用vue-test-utils來測試使用pinia的組件,需要修改pinia中存儲的state的值,但是嘗試了很多方法都無濟於事。 原始組件和存儲文件如下。

// HelloWorld.vue
<template>
    <h1>{{ title }}</h1>
</template>

<script>
import { useTestStore } from "@/stores/test";
import { mapState } from "pinia";

export default {
    name: "HelloWorld",
    
    computed: {
        ...mapState(useTestStore, ["title"]),
    },
};
</script>
// @/stores/test.js
import { defineStore } from "pinia";

export const useTestStore = defineStore("test", {
    state: () => {
        return { title: "hhhhh" };
    },
});

已嘗試以下方法。

  1. 將組件內使用的 store 導入到測試代碼中,直接進行更改,但更改不會影響組件。
// test.spec.js
import { mount } from "@vue/test-utils";
import { createTestingPinia } from "@pinia/testing";
import HelloWorld from "@/components/HelloWorld.vue";
import { useTestStore } from "@/stores/test";

test("pinia in component test", () => {
 const wrapper = mount(HelloWorld, {
     global: {
         plugins: [createTestingPinia()],
     },
 });
 const store = useTestStore();
 store.title = "xxxxx";

 console.log(wrapper.text()) //"hhhhh";
});
  1. 使用 initialState 試圖覆蓋原始存儲的內容,但再次沒有任何效果。
// test.spec.js
import { mount } from "@vue/test-utils";
import { createTestingPinia } from "@pinia/testing";
import HelloWorld from "@/components/HelloWorld.vue";

test("pinia in component test", () => {
 const wrapper = mount(HelloWorld, {
     global: {
         plugins: [createTestingPinia({ initialState: { title: "xxxxx" } })],
     },
 });
 console.log(wrapper.text()) //"hhhhh";
});
  1. 修改測試代碼中傳遞給 global.plugins 的 TestingPinia 對象,但同樣沒有效果。
// test.spec.js
import { mount } from "@vue/test-utils";
import { createTestingPinia } from "@pinia/testing";
import HelloWorld from "@/components/HelloWorld.vue";

test("pinia in component test", () => {
 const pinia = createTestingPinia();
 pinia.state.value.title = "xxxxx";
 const wrapper = mount(HelloWorld, {
     global: {
         plugins: [pinia],
     },
 });
 console.log(wrapper.text()) //"hhhhh";
});
  1. 使用 global.mocks 來模擬組件中使用的狀態,但這僅適用於組件中使用 setup() 傳入的狀態,而使用 mapState() 傳入的狀態無效。
// test.spec.js
import { mount } from "@vue/test-utils";
import { createTestingPinia } from "@pinia/testing";
import HelloWorld from "@/components/HelloWorld.vue";

test("pinia in component test", () => {
 const wrapper = mount(HelloWorld, {
     global: {
         plugins: [createTestingPinia()],
         mocks: { title: "xxxxx" },
     },
 });
 console.log(wrapper.text()) //"hhhhh"
});

這已使用jest.mock()解決。

import { mount } from "@vue/test-utils";
import { createPinia } from "pinia";
import HelloWorld from "@/components/HelloWorld.vue";

jest.mock("@/stores/test", () => {
    const { defineStore } = require("pinia");
    const useTestStore = defineStore("test", { state: () => ({ title: "xxxxx" }) });
    return { useTestStore };
});

test("pinia in component test", () => {
    const wrapper = mount(HelloWorld, {
        global: { plugins: [createPinia()] },
    });
    expect(wrapper.text()).toBe("xxxxx");
});

感謝 Red Panda 提供這個主題。 我使用“testing-library”和“vue-testing-library”而不是“vue-test-utils”和“jest”,但問題是一樣的 - 無法更改商店的 pinia 初始數據。 我終於找到了解決此問題的方法,而無需模擬該功能。 當你 $patch 數據時,你只需要等待它。 不知何故,它有幫助。 我的代碼看起來像這樣,它完全有效:

Popup.test.js

import { render, screen } from '@testing-library/vue'
import { createTestingPinia } from '@pinia/testing'
import { popup } from '@/store1/popup/index'
import Popup from '../../components/Popup/index.vue'

describe('Popup component', () => {
  test('displays popup with group component', async () => {
    render(Popup, {
      global: { plugins: [createTestingPinia()] }
    })
    const store = popup()
    await store.$patch({ popupData: 'new name' })
    screen.debug()
  })
})

或者您可以使用以下方案設置 initialState:

import { render, screen } from '@testing-library/vue'
import { createTestingPinia } from '@pinia/testing'
import { popup } from '@/store1/popup/index'
import Popup from '../../components/Popup/index.vue'

  test('displays popup with no inner component', async () => {
    const { getByTestId } = render(Popup, {
      global: {
        plugins: [
          createTestingPinia({
            initialState: {
              popup: {
                popupData: 'new name'
              }
            }
          })
        ]
      }
    })
    const store = popup()
    screen.debug()
  })

在 initialState 中的popup - 是從@/store1/popup導入的 pinia 商店。 您可以以相同的方式在那里指定其中的任何一個。

彈出窗口

<script>
import { defineAsyncComponent, markRaw } from 'vue'
import { mapState, mapActions } from 'pinia'
import { popup } from '@/store1/popup/index'

export default {
  data () {
    return {}
  },
  computed: {
    ...mapState(popup, ['popupData'])
  },
....

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM