text() 方法在 Blob 中不可用

问题描述 投票:0回答:2

我正在使用

jest
nock
进行一些集成测试来测试 Axios 拦截器 链接。
在其中一个中,我期望收到一个
Blob
实例
根据这个链接,我应该能够使用它的
text()
方法。
我的问题是:为什么没有定义这个方法?(在我的测试中)

这是(简化的)代码:

// interceptors.js
const useBlobTextProperty = async (response) => {
  const { data: myBlob } = response
  console.log(myBlob.toString())          // Prints "[object Blob]"
  response.rawText = await myBlob.text()  // TypeError: myBlob.text is not a function
  return response
}
// foo.test.js
import axios from 'axios'
import httpAdapter from 'axios/lib/adapters/http'
import nock from 'nock'

const testAxios = axios.create({
  responseEncoding: 'utf8',
  responseType: 'blob',
})
testAxios.interceptors.response.use(useBlobTextProperty, null)

const host = 'http://localhost'

axios.defaults.host = host
axios.defaults.adapter = httpAdapter

describe('SO test', () => {
  beforeEach(() => {
    nock(host)
      .defaultReplyHeaders({ 'Content-Type': 'application/json' })
      .persist()
      .get('/')
      .reply(200, { foo: 17 })
  })
  afterEach(() => {
    nock.cleanAll()
  })

  it('should get raw text', async () => {
    const returnValue = await testAxios.get('/') // FAIL: TypeError
    expect(returnValue.rawText).toEqual('{"foo":17}')
  }, 1000)
})

仅供参考,为了解决此问题,我正在使用另一个拦截器:

// interceptors.js
const addMissingTextPropertyToBlob = (response) => {
  const { data } = response
  if (data.toString() === '[object Blob]' && !data.text) {
    data.text = () =>
      new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = () => { resolve(reader.result) }
        reader.onerror = (error) => { reject(error) }
        reader.readAsText(data)
      })
  }
  return response
}
// foo.test.js
// Response interceptors are executed from index 0 to N-1
testAxios.interceptors.response.use(addMissingTextPropertyToBlob, null)
testAxios.interceptors.response.use(useBlobTextProperty, null)
// Then, it works!

但我想了解为什么我在测试中不能依赖

Blob.text()

javascript axios jestjs blob nock
2个回答
7
投票

就我而言,这种方法对我有用:

yarn add blob-polyfill -D

然后在你的笑话中导入以下内容

setupTests

import 'blob-polyfill';


0
投票

问题

问题来自 JSDom 中的 Blob 问题,Jest 在运行测试时在后台使用它作为环境。 JSDom 的

Blob
实现不支持
text
stream
arrayBuffer
方法。

解决方案

因此,您可以使用

blob-polyfill
库,正如 @washington-braga 所说。还有一种没有外部依赖性的选项。您可以使用本机 Node.js 覆盖 Blob 的 JSDom 版本,如下所示

import {Blob as BlobPolyfill} from 'node:buffer';

global.Blob = BlobPolyfill as any;

我检查过它适用于 Node 18.18.2。

如果你使用纯 JavaScript,我认为这段代码应该有帮助(我没有检查)

global.Blob = require('node:buffer').Blob;
© www.soinside.com 2019 - 2024. All rights reserved.