如何使用 Jasmine (Angular) 对下载文件进行单元测试?

mpr*_*ahl 9 javascript jasmine angular

我有一个 Angular 6 应用程序,它有一个“导出到 CSV”按钮,单击该按钮时,会在生成要下载的 CSV 文本的组件上运行一个方法。然后使用以下代码下载该文件:

const tempLink = document.createElement('a');
tempLink.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
tempLink.target = '_blank';
tempLink.download = 'export.csv';
tempLink.click();
Run Code Online (Sandbox Code Playgroud)

如何在不触发实际下载的情况下对单击“导出到 CSV”按钮进行单元测试?

唯一的方法是在 HTML 中创建链接(不是动态的),然后在链接的点击事件上使用 Jasmine 间谍吗?

Bri*_*ams 15

您可以将Jasmine 间谍函数(spyOn、spyOnProperty、jasmine.createSpy、jasmine.createSpyObj)与和 方法结合使用来监视和模拟行为。

在这种情况下,您可以模拟document.createElement()返回一个间谍对象,您可以使用该对象来验证是否设置并click()调用了正确的属性。

这是一个工作示例:


示例.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-example',
  template: '<div><button (click)="download()">Download Csv</button></div>'
})
export class ExampleComponent implements OnInit {

  constructor() { }

  ngOnInit() { }

  download() {
    const csvContent = this.generateCsv();
    const tempLink = document.createElement('a');
    tempLink.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
    tempLink.target = '_blank';
    tempLink.download = 'export.csv';
    tempLink.click();
  }

  private generateCsv() {
    return 'ID,Name\n1,abc\n2,def\n';
  }

}
Run Code Online (Sandbox Code Playgroud)

示例.component.spec.ts

import { ExampleComponent } from './example.component';

describe('ExampleComponent', () => {

  it('should download the csv file', () => {
    // create spy object with a click() method
    const spyObj = jasmine.createSpyObj('a', ['click']);
    // spy on document.createElement() and return the spy object
    spyOn(document, 'createElement').and.returnValue(spyObj);

    const comp = new ExampleComponent();
    comp.download();

    expect(document.createElement).toHaveBeenCalledTimes(1);
    expect(document.createElement).toHaveBeenCalledWith('a');

    expect(spyObj.href).toBe('data:text/csv;charset=utf-8,ID,Name%0A1,abc%0A2,def%0A');
    expect(spyObj.target).toBe('_blank');
    expect(spyObj.download).toBe('export.csv');
    expect(spyObj.click).toHaveBeenCalledTimes(1);
    expect(spyObj.click).toHaveBeenCalledWith();
  });

});
Run Code Online (Sandbox Code Playgroud)

  • @MitchellBrooks我遇到了同样的错误,就我而言,这是因为我正在测试的函数中有一个 document.body.appendChild 。我通过添加 `spyOn(document["body"], 'appendChild');` 来解决。 (2认同)