有两种方法可以在Jest中模拟全局变量:
- 使用
mockImplementation
方法(最像玩笑的方式),但是它仅对那些具有的默认实现的变量有效jsdom
,window.open
是其中之一:
test('it works', () => {
const mockedOpen = jest.fn();
const originalWindow = { ...window };
const windowSpy = jest.spyOn(global, "window", "get");
windowSpy.mockImplementation(() => ({
...originalWindow,
open: mockedOpen
}));
statementService.openStatementsReport(111)
expect(mockedOpen).toBeCalled();
windowSpy.mockRestore();
});
- 将值直接分配给全局属性,最直接的方法是,但是可能会触发某些
window
变量的错误消息,例如window.href
。
test('it works', () => {
const mockedOpen = jest.fn();
const originalOpen = window.open;
window.open = mockedOpen;
statementService.openStatementsReport(111)
expect(mockedOpen).toBeCalled();
window.open = originalOpen;
});
- 不要直接使用全局变量(需要一些重构)
与其直接使用全局值,不如从另一个文件中导入它更清洁,因此使用Jest进行模拟将变得微不足道。
./test.js
jest.mock('./fileWithGlobalValueExported.js');
import { windowOpen } from './fileWithGlobalValueExported.js';
import { statementService } from './testedFile.js';
test('it works', () => {
statementService.openStatementsReport(111)
expect(windowOpen).toBeCalled();
});
./fileWithGlobalValueExported.js
export const windowOpen = window.open;
./testedFile.js
import { windowOpen } from './fileWithGlobalValueExported.js';
export const statementService = {
openStatementsReport(contactIds) {
windowOpen(`a_url_${contactIds}`);
}
}