jest で Blob をモックにしてテストしたかったのですが、Node.js に Blob は定義されていませんでした。
未定義なので定義することで対応してみました。
作成したコード
まずはテスト対象のコードです。前回のコードを typescript で別ファイルにしました。
export default function downloadText(fileName: string, text: string) {
    const blob = new Blob([text], { type: 'text/plain' });
    const aTag = document.createElement('a');
    aTag.href = URL.createObjectURL(blob);
    aTag.target = '_blank';
    aTag.download = fileName;
    aTag.click();
    URL.revokeObjectURL(aTag.href);
  }そして、テストコードは以下です。
ここでは意図した値で Blob を作成したか?を確認し、Aタグについては割愛しています。
import downloadText from './downloadText';
class BlobMock {
  constructor(
    content: Array<ArrayBuffer | ArrayBufferView | Blob | String> | undefined,
    options: BlobPropertyBag | undefined,
  ) {
    this.content = content;
    this.options = options;
  }
  public content: Array<ArrayBuffer | ArrayBufferView | Blob | String> | undefined;
  public options: BlobPropertyBag | undefined;
}
test('downloadText', () => {
  (global as any).Blob = BlobMock;
  const backup1 = window.URL.createObjectURL;
  const backup2 = window.URL.revokeObjectURL;
  window.URL.createObjectURL = jest.fn();
  window.URL.revokeObjectURL = jest.fn();
  downloadText('sample.txt', '一富士二鷹三茄子');
  expect(window.URL.createObjectURL).toBeCalledWith({
    content: ['一富士二鷹三茄子'],
    options: { type: 'text/plain' },
  });
  window.URL.createObjectURL = backup1;
  window.URL.revokeObjectURL = backup2;
});悩んだポイント1:どう Blob を定義するか
未定義だからといって、
  global.Blob = BlobMock;にすると、“A file-like object of immutable, raw data. Blobs represent data that isn’t necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user’s system.” と言われてしまうので、
  (global as any).Blob = BlobMock;の通り、global を一旦 any にして Blob を設定しています。
悩んだポイント2:URL.createObjectURL をモックにできない
モックにできないというか、
  jest.spyOn(window.URL, 'createObjectURL').mockImplementation(jest.fn());だと、
Cannot spy the createObjectURL property because it is not a function; undefined given insteadとなってしまうので、関数を定義することで乗り越えました。
 
 


コメント