在Jest中编写单元测试用例时,document.getElementById中的文档未定义

时间:2018-09-25 13:37:24

标签: reactjs jestjs

我已经使用以下代码编写了禁用按钮的代码:

document.getElementBydId('btn')。disabled = true;

此调用写在componentWillUnmount生命周期事件的react中。之所以使用这种方式,是因为该按钮来自公共存储库,无法在我的组件内部直接访问。

现在,此组件的所有单元测试用例均失败,并得到“ document”为null的错误。我们在开玩笑地编写单元测试用例。

任何人都可以帮忙。

2 个答案:

答案 0 :(得分:0)

这是不鼓励在React中直接使用DOM的原因之一。

document.getElementById('btn').disabled应该通过JSDOM或明确地存根变量来提供和模拟。

JSDOM可以应用于全局范围https://askubuntu.com/questions/133389/no-such-file-or-directory-but-the-file-exists或与directly一起使用(默认情况下是使用JSDOM对DOM进行存根)。

它也可以带有以下内容:

beforeEach(() => {
  global.document = {
    getElementById: jest.fn()
  }
});

afterEach(() => {
  delete global.document;
});

it('...', () => {
  document.getElementById.mockReturnValue({ disabled: true });
  ...
  expect(document.getElementById).toHaveBeenCalledWith('btn');
});

答案 1 :(得分:0)

您需要在测试用例中模拟getElementById。

然后,您可以测试是否使用正确的参数调用了getElementById并将其disabled设置为true(假设之前为false)。

expect(document.getElementById).toHaveBeenCalled();
expect(document.getElementById.mock.calls[0][0]).toBe("btn");
expect(btnParams.disabled).toBeTruthy();

我为此创建了一个有效的测试用例,可以在https://codesandbox.io/s/jznv48w32v

中找到

请注意,我们在测试用例中使用beforeEach和afterAll。 在每个测试用例之后,beforeEach都会重置我们的模拟功能。 afterAll用于将模拟函数的值恢复为原始值。