如何在Vitest中实现静态资源的HTTP访问?(Astro应用场景)
解决方案
方案一:在Vitest中配置静态文件服务器(推荐)
因为hyparquet依赖HTTP范围请求,直接读取本地文件路径无法满足需求,最稳妥的方式是在测试阶段启动一个支持范围请求的静态服务器,测试结束后自动销毁:
- 安装依赖
npm install -D serve-handler http
- 创建测试前置文件
vitest.setup.ts
import { createServer } from 'http'; import serveHandler from 'serve-handler'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const publicDir = join(__dirname, '../public'); // 对应项目中public文件夹的实际路径 let server: ReturnType<typeof createServer>; // 所有测试前启动服务器 beforeAll(async () => { server = createServer((req, res) => { return serveHandler(req, res, { public: publicDir, headers: { 'Access-Control-Allow-Origin': '*', }, }); }); await new Promise<void>((resolve) => { server.listen(5174, () => { resolve(); }); }); }); // 所有测试结束后关闭服务器 afterAll(async () => { await new Promise<void>((resolve, reject) => { server.close((err) => { if (err) reject(err); else resolve(); }); }); });
- 修改Vitest配置文件
vitest.config.ts
import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { setupFiles: ['./vitest.setup.ts'], environment: 'jsdom', // 适配客户端代码测试环境 }, });
- 在测试代码中访问文件
import { test } from 'vitest'; import { ParquetReader } from 'hyparquet'; test('读取Parquet文件', async () => { const reader = await ParquetReader.openUrl('http://localhost:5174/your-file.parquet'); // 编写你的测试逻辑 await reader.close(); });
serve-handler 默认支持HTTP范围请求,完全匹配hyparquet的性能需求。
方案二:调整文件存储位置,利用Vitest内置服务
如果不想额外搭建服务器,可以将Parquet文件移至src/assets目录,通过Vitest的资源解析能力实现HTTP访问:
将
your-file.parquet移动到src/assets目录下修改Vitest配置
import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { environment: 'jsdom', server: { fs: { strict: false, // 允许访问项目根目录内的文件 }, }, }, });
- 在测试代码中访问文件
import { test } from 'vitest'; import { ParquetReader } from 'hyparquet'; import parquetFile from './assets/your-file.parquet?url'; test('读取Parquet文件', async () => { const reader = await ParquetReader.openUrl(parquetFile); // 编写你的测试逻辑 await reader.close(); });
注:此方案依赖Vitest jsdom环境的资源解析能力,若遇到范围请求不支持的情况,优先切换到方案一。
方案三:手动模拟范围请求(应急方案)
如果临时不想搭建服务器,可以通过拦截fetch请求手动处理范围逻辑,但实现相对繁琐:
import { test, vi } from 'vitest'; import { ParquetReader } from 'hyparquet'; import fs from 'fs/promises'; import path from 'path'; vi.stubGlobal('fetch', async (url: string) => { const filePath = path.resolve(__dirname, '../public', new URL(url).pathname); const fileBuffer = await fs.readFile(filePath); // 若需处理Range请求,需手动解析请求头并返回对应片段 return new Response(fileBuffer, { headers: { 'Content-Type': 'application/octet-stream', 'Accept-Ranges': 'bytes', 'Content-Length': fileBuffer.length.toString(), }, }); }); test('读取Parquet文件', async () => { const reader = await ParquetReader.openUrl('/your-file.parquet'); // 编写你的测试逻辑 await reader.close(); });
内容的提问来源于stack exchange,提问作者Ed Staub
相关产品推荐
相关产品推荐

