编写AngularJS Jest测试遇window未定义,求jest-environment-jsdom替代方案
无需额外依赖解决AngularJS Jest测试中window未定义的方案
以下是几种不需要安装jsdom或VS Build tools的替代方案,按需选择:
1. 手动在测试文件顶部模拟全局window对象
直接在测试文件的最顶部(所有import/require之前)挂载模拟的window对象到Node的global上,按需补充代码用到的属性:
// 测试文件顶部 global.window = { // 按需添加你的代码依赖的属性,比如location、localStorage等 location: { href: 'http://mock-url.com' }, localStorage: { getItem: jest.fn(), setItem: jest.fn() }, alert: jest.fn() }; // 若代码依赖document,可一并模拟 global.document = { createElement: jest.fn(), querySelector: jest.fn().mockReturnValue({}) };
如果需要模拟只读属性(比如window.top),可以用Object.defineProperty:
Object.defineProperty(global.window, 'top', { value: global.window, writable: false });
2. 在Jest配置中全局注入window
修改项目的jest.config.js(或package.json中的jest配置块),通过globals字段全局声明window和document:
// jest.config.js module.exports = { globals: { window: {}, document: {} }, // 其他jest配置... };
这种方式会让所有测试文件都能访问到全局的window对象,后续可以在单个测试中补充具体属性。
3. 针对性Mock依赖window的功能
如果你的代码只是用到window的某个特定方法/属性,不用模拟整个window,只需要Mock对应的部分即可。比如测试依赖window.location.href的服务:
// 测试依赖window的服务 describe('MyService', () => { let myService; beforeEach(() => { angular.mock.module('app'); // 在注入服务前,Mock需要的window属性 global.window.location = { href: 'http://test.example.com' }; inject(function(_MyService_) { myService = _MyService_; }); }); it('should get correct current URL', () => { expect(myService.getCurrentUrl()).toBe('http://test.example.com'); }); });
4. 使用Jest SpyOn模拟window方法
如果需要跟踪window方法的调用(比如alert、console.log),可以用jest.spyOn来模拟:
beforeEach(() => { // 确保window存在 global.window = global.window || {}; // Mock window.alert方法 jest.spyOn(window, 'alert').mockImplementation(() => {}); }); afterEach(() => { // 测试后恢复原方法 jest.restoreAllMocks(); }); it('should call alert on error', () => { myService.triggerError(); expect(window.alert).toHaveBeenCalledWith('Error occurred'); });
内容的提问来源于stack exchange,提问作者MonkBen
相关产品推荐
相关产品推荐

