Jest 是一个基于 Node 的运行器。这意味着测试始终在 Node 环境中运行,而不是在真实的浏览器中运行。
Jest 由 jsdom 提供了浏览器全局变量, 例如 window, 但它们只是真实浏览器行为的近似值。
由于 jsdom 库的更改,localStorage不能像往常一样被mock或spy。
const localStorageSpy = jest.spyOn(localStorage, 'setItem');
expect(localStorageSpy).toBeCalledTimes(1);
// Matcher error: received value must be a mock or spy function
解决方法: 在测试文件的describe()之前重写localStorage
const localStorageMock = (() => {
let store = {};
return {
getItem: key => store[key] || null,
setItem: (key, value) => {
store[key] = value;
},
removeItem: key => {
delete store[key];
},
clear: () => {
store = {};
}
};
})();
Object.defineProperty(window, 'localStorage', {
value: localStorageMock
});
但localStorage自身的功能是正常的,在Jest中可以缓存值,不需要重写localStorage
// component.ts
this.name = localStorage.getItem('userInfo')?.['name'];
// spec.ts
const data = {name: 'John'}
localStorage.setItem('userInfo', data);
const expectedName = localStorage.getItem('userInfo');
expect(component.name).toEqual(expectedName.name);
jsdom 是许多 Web 标准(特别是DOM 和 HTML)的纯 JavaScript 实现,用于 Node.js。通常,它的目的是模拟足够多的 Web 浏览器子集,以便于测试和抓取实际的 Web 应用程序。