为笑话测试而存储的mock样本



嘿,也许有人能帮我一下?我尝试用自定义值和操作来模拟一个zustand存储。我想在我的测试文件中进行模拟。但我失败得很惨

这是我的react应用程序的一个简化示例。

component.jsx

import React from "react";
import useStore from "@app/component_store";
export default function Component() {
const foo = useStore((state) => state.foo);
const setFoo = useStore((state) => state.foo_set);
return (
<>
<div data-testid="foo">{foo}</div>
<button data-testid="btn-foo" onClick={() => setFoo("new foo")}>
set foo
</button>
</>
);
}

component_store.jsx

import create from "zustand";
const useStore = create((set) => ({
foo: "foo",
foo_set: (value) => set(() => ({ foo: value })),
}));
export default useStore;

component.test.jsx

/* global  afterEach, expect, jest, test  */
import React from "react";
import { cleanup, fireEvent, render } from "@testing-library/react";
import "@testing-library/jest-dom";
import mockCreate from "zustand";
import Component from "@app/component";
jest.mock("@app/component_store", () => (args) => {
const useStore = mockCreate((set, get) => ({
foo: "mocked foo",
foo_set: (value) => set(() => ({ foo: "mocked set foo" })),
}));
return useStore(args);
});
afterEach(cleanup);
test("override store values and actions", () => {
const { container, getByTestId } = render(<Component />);
const foo = getByTestId("foo");
const btnFoo = getByTestId("btn-foo");
expect(foo.textContent).toBe("mocked foo");
fireEvent.click(btnFoo);
expect(foo.textContent).toBe("mocked set foo");
});

这个失败。expect(foo.textContent).toBe("mocked set foo");仍将拥有"模拟食物"。作为一个值,尽管模拟的foo_set被调用(例如,添加控制台日志确实被记录)。但同样,foo的值不会更新。

但是,如果我将存储模拟部分移到它自己的文件中,并将其导入到我的测试中,那么一切都会如预期的那样工作。

component_store_mocked.jsx

注意:这与component.test.jsx

中的相同
import create from "zustand";
const useStore = create((set, get) => ({
foo: "mocked foo",
foo_set: (value) => set(() => ({ foo: "mocked set foo" })),
}));
export default useStore;
<<p>更新strong> component.test.jsx
/* global  afterEach, expect, jest, test  */
import React from "react";
import { cleanup, fireEvent, render } from "@testing-library/react";
import "@testing-library/jest-dom";
import mockCreate from "zustand";
import Component from "@app/component";
// this part here
import mockComponentStore from "@app/component_store_mocked";
jest.mock("@app/component_store", () => (args) => {
const useStore = mockComponentStore;
return useStore(args);
});
afterEach(cleanup);
test("override store values and actions", () => {
const { container, getByTestId } = render(<Component />);
const foo = getByTestId("foo");
const btnFoo = getByTestId("btn-foo");
expect(foo.textContent).toBe("mocked foo");
fireEvent.click(btnFoo);
expect(foo.textContent).toBe("mocked set foo");
});

我想在测试文件中做模拟,而不是用几十个模拟存储来污染我的系统。同样,这只是一个更大的应用程序的简化设置。

我也遇到过同样的问题,我是这样解决的:

我使用React Native,所以我插入了Zustand的模拟来重置每个测试的状态。https://docs.pmnd.rs/zustand/guides/testing

我在存储库中创建了一个名为_mock的操作,该操作接收对象并将其插入到存储库中。

模拟行动:

_mock(store) {
set({
state: { ...get().state, ...store },
actions: get().actions,
});
},

模拟动作类型:

_mock: (store: Partial<RootStateAuth>) => void;

用法:

useAuthStore.getState().actions._mock({
role: 'purchases',
registrationCompleted: false,
name: 'Fulano',
});

我希望这对你有帮助。

您可以使用jest mock模拟测试中从存储返回的数据。

当你在函数中调用UseWhateverStore时,你检索了一个函数,它将状态作为参数传递,然后当你说state时。如果它从store返回那个状态。

下面是一个模拟 的例子
jest.mock("../stores/accounts-store.ts", () => ({
useAccountsStore: (passedFunction: any) => {
const data = {
createNewAccount: jest.fn(),
getFactions: jest.fn(),
factions: []
}
return passedFunction(data);
}
}));

最新更新