如何使用 jest 模拟 FileReader

Ajj*_*Hsh 3 javascript jestjs

我需要模拟一个FileReader使用 jest的函数。特别是函数readAsBinaryStringonload

我已经创建了一些代码:

FileReader.readAsBinaryString = () => mock.mockReturnValue(null);
Run Code Online (Sandbox Code Playgroud)

但它不起作用。我如何FileReader使用玩笑来模拟和您的功能?

测试功能:

handleFileUpload(event) {
  let reader = new FileReader();
  let file = event.target.files[0];

  reader.readAsBinaryString(file);

  reader.onload = () => {
    let base64String = btoa(reader.result);
    this.object.image = 
  };
},
Run Code Online (Sandbox Code Playgroud)

sli*_*wp2 5

您可以使用jest.spyOn(对象,方法名,存取类型?)来刺探readAsBinaryString的方法FileReaderreadAsBinaryString是一个实例方法,而不是FileReader构造函数的静态方法。此外,返回值readAsBinaryStringvoid。所以你不能模拟返回值。

例如

index.ts

export function main() {
  const fr = new FileReader();
  const blob = new Blob();
  fr.readAsBinaryString(blob);
}
Run Code Online (Sandbox Code Playgroud)

index.spec.ts,我们需要 spy on FileReader.prototype.readAsBinaryString,因为它是一个实例方法。

import { main } from './';

describe('main', () => {
  test('should mock FileReader', () => {
    const readAsBinaryStringSpy = jest.spyOn(FileReader.prototype, 'readAsBinaryString');
    main();
    expect(readAsBinaryStringSpy).toBeCalledWith(new Blob());
  });
});
Run Code Online (Sandbox Code Playgroud)

100% 覆盖率的单元测试结果:

PASS  src/stackoverflow/58644737/index.spec.ts
  main
    ? should mock FileReader (10ms)

----------|----------|----------|----------|----------|-------------------|
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:        4.852s, estimated 9s
Run Code Online (Sandbox Code Playgroud)

更新

index.ts

export class Component {
  object = {
    image: ''
  };
  handleFileUpload(event) {
    let reader = new FileReader();
    let file = event.target.files[0];

    reader.readAsBinaryString(file);

    reader.onload = () => {
      let base64String = btoa(reader.result as string);
      this.object.image = base64String;
    };

    return reader;
  }
}
Run Code Online (Sandbox Code Playgroud)

index.spec.ts

import { Component } from './';

const cmp = new Component();

describe('main', () => {
  beforeEach(() => {
    jest.restoreAllMocks();
  });
  test('should test handle file upload correctly', () => {
    const mFile = new File(['go'], 'go.pdf');
    const mEvent = { target: { files: [mFile] } };
    const readAsBinaryStringSpy = jest.spyOn(FileReader.prototype, 'readAsBinaryString');
    const btoaSpy = jest.spyOn(window, 'btoa');
    const reader = cmp.handleFileUpload(mEvent);
    expect(reader).toBeInstanceOf(FileReader);
    if (reader.onload) {
      Object.defineProperty(reader, 'result', { value: 'gogo' });
      const mOnloadEvent = {} as any;
      reader.onload(mOnloadEvent);
      expect(btoaSpy).toBeCalledWith('gogo');
      expect(cmp.object.image).toBe(btoa('gogo'));
    }
    expect(readAsBinaryStringSpy).toBeCalledWith(mFile);
  });
});
Run Code Online (Sandbox Code Playgroud)

100% 覆盖率的单元测试结果:

 PASS  src/stackoverflow/58644737/index.spec.ts (7.328s)
  main
    ? should test handle file upload correctly (13ms)

----------|----------|----------|----------|----------|-------------------|
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:        8.78s
Run Code Online (Sandbox Code Playgroud)

源代码:https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58644737