noo*_*oob 10 reactjs jestjs zustand
嘿,也许有人可以帮我解决这个问题?我尝试使用自定义值和操作来模拟 zustand 商店。我想在我的测试文件中进行模拟。但我却惨遭失败。
这是我的反应应用程序的简化示例。
组件.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>
</>
);
}
Run Code Online (Sandbox Code Playgroud)
组件存储.jsx
import create from "zustand";
const useStore = create((set) => ({
foo: "foo",
foo_set: (value) => set(() => ({ foo: value })),
}));
export default useStore;
Run Code Online (Sandbox Code Playgroud)
组件.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");
});
Run Code Online (Sandbox Code Playgroud)
这失败了。expect(foo.textContent).toBe("mocked set foo");
仍然会有“mocked 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;
Run Code Online (Sandbox Code Playgroud)
更新了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");
});
Run Code Online (Sandbox Code Playgroud)
我很乐意在测试文件中进行模拟,而不是用数十个模拟商店来污染我的系统进行测试......同样,这只是一个更大的应用程序的简化设置。
小智 0
我有同样的问题,我是这样解决的:
我正在使用 React Native,因此我插入了 Zustand 的模拟来重置每个测试的状态。https://docs.pmnd.rs/zustand/guides/testing
我在存储中创建了一个名为 _mock 的操作,它接收一个对象并将其插入到存储中。
模拟动作:
_mock(store) {
set({
state: { ...get().state, ...store },
actions: get().actions,
});
},
Run Code Online (Sandbox Code Playgroud)
模拟动作类型:
_mock: (store: Partial<RootStateAuth>) => void;
Run Code Online (Sandbox Code Playgroud)
用法:
useAuthStore.getState().actions._mock({
role: 'purchases',
registrationCompleted: false,
name: 'Fulano',
});
Run Code Online (Sandbox Code Playgroud)
我希望它有帮助。
归档时间: |
|
查看次数: |
8689 次 |
最近记录: |