我有一个发出API请求的javascript实用程序文件。它有两个条件位于顶部,依赖于window.VarA和window.VarB。 VarA和VarB是我们的软件给窗口赋予的变量。如果设置它们,则运行条件内的代码。由于此文件实际上不呈现窗口,因此我无法将这些属性设置为任何内容,并在条件内获取代码覆盖率。
我试图渲染一个默认窗口,但似乎不起作用。我可以使用Jest和Enzyme。
我正在测试的对象的代码看起来像这样
let param = "";
let url = "";
if(window.VarA !== underfined){
param = window.VarA; <<--need coverage here
}
if(window.VarB !== underfined){
url = window.VarB; <<--need coverage here
}
有没有办法为我的测试模拟这些窗口属性?
test environment的默认Jest
是一个类似浏览器的环境,使用jsdom
提供window
对象。
如果测试环境是jsdom
,那么window
对象可以作为window
或global
访问。
然后在window
上设置变量就像执行以下操作一样简单:
window.VarA = 'foo'; // global.VarA works as well
window.VarB = 'bar'; // global.VarB works as well
更棘手的部分是在代码运行之前设置这些变量。
考虑以下config.js
模块:
let param = "";
let url = "";
if (window.VarA !== undefined) {
param = window.VarA;
}
if (window.VarB !== undefined) {
url = window.VarB;
}
export const config = {
param,
url
}
如果你使用require
,那么在需要模块之前代码不会运行,允许进行如下测试:
test('setting window variables', () => {
window.VarA = 'foo'; // global.VarA works as well
window.VarB = 'bar'; // global.VarB works as well
const { config } = require('./config'); // now require the module
expect(config.param).toBe('foo'); // SUCCESS
expect(config.url).toBe('bar'); // SUCCESS
});
另一方面,如果你使用import
,那么在测试运行之前需要在window
上定义变量,因为imports are hoisted在任何测试代码运行之前发生:
import { config } from './config'; // this runs first
test('setting window variables', () => {
window.VarA = 'foo'; // <= this doesn't affect config
window.VarB = 'bar'; // <= this doesn't affect config
expect(config.param).toBe('foo'); // FAIL
expect(config.url).toBe('bar'); // FAIL
});
因此,如果你正在使用import
,那么在测试开始运行之前你需要使用类似setupFilesAfterEnv
的东西设置window
变量:
// Configure Jest using setupFilesAfterEnv
// to run a module that sets the window variables
// so they are already set before the test begins...
import { config } from './config';
test('setting window variables', () => {
expect(config.param).toBe('foo'); // SUCCESS
expect(config.url).toBe('bar'); // SUCCESS
});