Reactjs&Jest,测试操作也会改变本地存储



在我的 react + redux 应用程序中,我有一个操作,除了返回类型和有效负载外,还会更改 localStorage,例如:

export const cancel = () => {
localStorage.removeItem("MyAppData");
return { type: types.USER_CANCEL};
};

我的测试如下所示:

test("user cancels", () => {
const action = actions.cancel();
expect(action).toEqual({
type: types.USER_CANCEL
});
});

没有为本地存储编写任何测试,我得到

● user cancels
ReferenceError: localStorage is not defined
33 |
34 | export const cancel = () => {
> 35 |   localStorage.removeItem("MyAppData");
|   ^
36 |   return { type: types.USER_CANCEL};
37 | };
38 |
at Object.localStorage [as cancel] (src/actions/AllActions.js:35:3)
at Object.cancel (__test__/actions/AllActions.test.js:56:26)

因此,我为本地存储做了一个模拟

const mockStorage = {};
const localStorage = {
setItem: (key, val) => Object.assign(mockStorage, { [key]: val }),
getItem: key => mockStorage[key],
removeItem: key => {delete mockStorage[key];console.log("Deleted: ", key);},
clear: () => mockStorage
};
export default localStorage;

导入此模拟或使用本地存储 API,我仍然收到相同的错误

我对如何测试当我调用cancel()时也调用localStorge.removeItem或删除键和值感到困惑?

出于某种原因,Jest 的测试环境中没有window.localStorage对象。我建议你将模拟分配给window对象。您可以在测试文件中beforeAll方法中执行此操作,也可以在此处为所有测试全局执行此操作。

之后,您的代码和测试将它用作本机本地存储:

test("user cancels", () => {
localStorage.setItem("MyAppData", "some_data");
const action = actions.cancel();
expect(action).toEqual({
type: types.USER_CANCEL
});
expect(localStorage.getItem("MyAppData")).toBeNull();
});

如果你在模拟localStorage,模拟它的所有方法,如removeItem,看看它是否被调用,你可以在它的mocked方法中使用console.log。

在jest.config里面.js

setupFiles: [
'./jest.globals.js'
],

玩笑全球.js

const mockStorage = {};
const localStorage = {
setItem: (key, val) => Object.assign(mockStorage, {[key]: val}),
getItem: key => mockStorage[key],
removeItem: key => { delete mockStorage[key]; console.log('Deleted: ' + key); },
clear: () => mockStorage,
};
global.localStorage = localStorage;

现在,localStorage 将在整个测试过程中在全球范围内可用。

要测试:

test("user cancels", () => {
const action = actions.cancel();
expect(action).toEqual({
type: types.USER_CANCEL
});
expect(localStorage.getItem("MyAppData")).toBeNull();
});

编辑:

作为最终的解决方案,更新您的jest.config.js以使用testEnvironment: "jsdom"这将使用 jsdom 的本地存储,您不再需要模拟它。

感谢@Ayushya和@Oleksandr科夫帕什科。我刚刚发现如果该应用程序是由CRA创建的,则整个方法要简单得多。因此,卸载所有软件包并恢复为CRA默认值。据我所知,只有一个答案提到了这一点。此外,我还在开玩笑文档中搜索更多答案在CRA文档中

所以创建src/setupTests.js

const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = localStorageMock;

默认情况下,CRA 的测试脚本为

"test": "react-scripts test --env=jsdom",

可以更改为node

最新更新