如何模拟用户创建的窗口属性?

问题描述 投票:2回答:1

我有一个发出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
}

有没有办法为我的测试模拟这些窗口属性?

javascript mocking
1个回答
1
投票

test environment的默认Jest是一个类似浏览器的环境,使用jsdom提供window对象。

如果测试环境是jsdom,那么window对象可以作为windowglobal访问。

然后在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
});
© www.soinside.com 2019 - 2024. All rights reserved.