我想测试一个使用 Jest 向 localStorage 写入内容的函数。
有问题的功能如下:
const items: = [
{
name: 'Item One',
},
];
export const init = () => {
if (!localStorage.getItem('items')) {
localStorage.setItem('items', JSON.stringify(items));
}
};
我当前的测试如下所示:
import { init } from './MyComponent';
describe('MyComponent', () => {
test('init method should set items to localStorage', () => {
init();
const items = JSON.parse(localStorage.getItem('items'));
expect(items).toEqual([
{
name: 'Item One',
},
]);
})
});
我在这里做错了什么或错过了什么?我正在直接导入并调用该函数,但我不确定测试是否像这样有意义。
希望有人可以指导我..
回答1
假设您使用的是 starter create-react-app 项目,localStorage 默认未在测试环境中定义。 https://github.com/facebook/create-react-app/blob/main/docusaurus/docs/running-tests.md#srcsetuptestsjs-1 指导用户进行如下设置(我必须将 as unknown as Storage
添加到 localStorageMock
因为没有它会出现编译错误):
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
clear: jest.fn()
};
global.localStorage = localStorageMock as unknown as Storage;
这可以添加到您的 setupTests.ts
文件中,也可以添加到您的测试套件文件中 - 在 describe
函数之外,或者在诸如 beforeAll
之类的套件设置函数中。
如您所见,上面明确地模拟了 localStorage
功能,这意味着将要被命中的逻辑将被模拟出来,并且不像在集成测试中那样运行。因此,我会将您的测试重构为以下代码,以确保调用 localStorage
以显示正确的行为:
test('init method should set items to localStorage', () => {
// act
init();
// assert
expect(localStorageMock.setItem).toHaveBeenCalled();
// option 1
expect(localStorageMock.setItem).toHaveBeenCalledWith('items', JSON.stringify([{name: 'Item One'}]))
// option 2
const args = localStorageMock.setItem.mock.calls[0];
expect(args[0]).toEqual('items');
expect(JSON.parse(args[1])[0].name).toEqual('Item One');
})
希望这可以帮助你!