如何测试对 void 函数中函数作用域变量的赋值?

How to test assignments to function scope variable in void function?

我有一个函数,由于代码覆盖问题,我需要对其进行测试。

const downloadPdfDataContent = (title: string, url: string): void => {
  const link = document.createElement('a');
  link.target = title;
  link.href = url;
  link.download = title;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

我怎样才能测试对变量和文档对象的赋值?我想我需要使用 spyOn .. 但我不知道具体如何,因为变量只存在于函数范围内。我考虑过简单地返回变量,但如果可能的话,我想阻止它。

一种方法是在测试中为实际的全局文档设置 onclick handler

如果您为 link 元素引入一些独特且可测试的东西(例如唯一 ID),那么您可以通过检查点击事件目标是瞬态 ID 来证明点击是对其进行的link.

此外,您可以检查 URL 它是否与正确的值对齐。

假设这是一个单元测试,即使获得任何点击事件也可能是一个合法的测试。

如果测试套件在浏览器上下文中 运行 并且您最好阻止导航,那么您的事件处理程序可以使用 preventDefault 来阻止任何导航的实际发生。

您可以使用 jest.spyOn() 模拟每个 DOM 操作。

例如

index.ts:

export const downloadPdfDataContent = (title: string, url: string): void => {
  const link = document.createElement('a');
  link.target = title;
  link.href = url;
  link.download = title;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

index.test.ts:

import { downloadPdfDataContent } from '.';

describe('67634069', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should pass', () => {
    const mAnchor = ({
      target: '',
      href: '',
      download: '',
      click: jest.fn(),
    } as unknown) as HTMLAnchorElement;
    const createElementSpy = jest.spyOn(document, 'createElement').mockReturnValueOnce(mAnchor);
    const appendChildSpy = jest.spyOn(document.body, 'appendChild').mockImplementation();
    const removeChildSpy = jest.spyOn(document.body, 'removeChild').mockImplementation();
    URL.revokeObjectURL = jest.fn();
    downloadPdfDataContent('teresa teng', 'example.com');
    expect(createElementSpy).toBeCalledWith('a');
    expect(appendChildSpy).toBeCalledWith(
      expect.objectContaining({
        target: 'teresa teng',
        href: 'example.com',
        download: 'teresa teng',
      })
    );
    expect(mAnchor.click).toBeCalledTimes(1);
    expect(removeChildSpy).toBeCalledWith(
      expect.objectContaining({
        target: 'teresa teng',
        href: 'example.com',
        download: 'teresa teng',
      })
    );
    expect(URL.revokeObjectURL).toBeCalledWith('example.com');
  });
});

测试结果:

 PASS  examples/67634069/index.test.ts (8.691 s)
  67634069
    ✓ should pass (4 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.612 s