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()
。
就我而言,这种方法对我有用:
yarn add blob-polyfill -D
然后在你的笑话中导入以下内容
setupTests
:
import 'blob-polyfill';
问题来自 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;