har*_*rry 16 javascript typescript vuejs3 vitest
我有一个简单的可组合项useRoles,需要测试
import { computed } from "vue";
import { useStore } from "./store";
export default function useRoles() {
const store = useStore();
const isLearner = computed(() => store.state.profile.currentRole === "learner");
return {
isLearner
};
}
Run Code Online (Sandbox Code Playgroud)
我的测试方法如下
import { afterEach, expect } from "vitest";
import useRoles from "./useRoles";
describe("useRoles", () => {
afterEach(() => {
vi.clearAllMocks();
vi.resetAllMocks();
});
it("should verify values when is:Learner", () => { // works
vi.mock("./store", () => ({
useStore: () => ({
state: {
profile: {
currentRole: "learner"
},
},
}),
}));
const { isLearner } = useRoles();
expect(isLearner.value).toBeTruthy();
});
it("should verify values when is:!Learner", () => { //fails
vi.mock("./store", () => ({
useStore: () => ({
state: {
profile: {
currentRole: "admin"
},
},
}),
}));
const { isLearner } = useRoles(); // Values are from prev mock
expect(isLearner.value).toBeFalsy();
});
});
Run Code Online (Sandbox Code Playgroud)
这useStore只是我打算模拟的一个简单函数
export function useStore() {
return {/**/};
}
Run Code Online (Sandbox Code Playgroud)
第一个测试成功运行,它具有我实现的所有模拟值,但问题是它没有为每个测试重置(根本不重置)。第二个测试具有上一个模拟的旧值。
我用过
vi.clearAllMocks();
vi.resetAllMocks();
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,清除或重置没有发生。
如何明确vi.mock每个测试的值?
事实证明我不应该被vi.mock多次打电话。这是主要的错误
用另一个模块替换提供的路径中的所有导入模块。您可以在路径中使用配置的 Vite 别名。对 vi.mock 的调用已被提升,因此在哪里调用它并不重要。它始终会在所有导入之前执行。
Vitest 静态分析您的文件以提升 vi.mock。这意味着您不能使用不是直接从 vitest 包(例如,从某些实用程序文件)导入的 vi
我的固定解决方案如下。
import useRoles from "./useRoles";
import { useStore } from "./store"; // Required the mock to work
vi.mock("./store");
describe("useRoles", () => {
afterEach(() => {
vi.clearAllMocks();
vi.resetAllMocks();
});
it("should verify values when is:Learner", () => {
// @ts-ignore it is a mocked instance so we can use any vitest methods
useStore.mockReturnValue({
state: {
profile: {
currentRole: "learner",
},
},
});
const { isLearner } = useRoles();
expect(isLearner.value).toBeTruthy();
});
it("should verify values when is:!Learner", () => {
// You need to use either @ts-ignore or typecast it
// as following (<MockedFunction<typeof useStore>>useStore)
// since original function has different type but vitest mock transformed it
(<MockedFunction<typeof useStore>>useStore).mockReturnValue({
state: {
profile: {
currentRole: "admin",
},
},
});
const { isLearner } = useRoles();
expect(isLearner.value).toBeFalsy();
});
});
Run Code Online (Sandbox Code Playgroud)
vitest = v0.23.0
我遇到了同样的问题并找到了解决方法。在你的情况下,它应该看起来像这样:
import { afterEach, expect } from "vitest";
import useRoles from "./useRoles";
vi.mock("./store");
describe("useRoles", () => {
it("should verify values when is:Learner", async () => {
const store = await import("./store");
store.useStore = await vi.fn().mockReturnValueOnce({
useStore: () => ({
state: {
profile: {
currentRole: "learner"
},
},
}),
});
const { isLearner } = useRoles();
expect(isLearner.value).toBeTruthy();
});
it("should verify values when is:!Learner", async () => {
const store = await import("./store");
store.useStore = await vi.fn().mockReturnValueOnce({
useStore: () => ({
state: {
profile: {
currentRole: "admin"
},
},
}),
});
const { isLearner } = useRoles(); // Value is from current mock
expect(isLearner.value).toBeFalsy();
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14524 次 |
| 最近记录: |