如何用MockedProvider结合apollo-upload-client模拟GraphQL文件上传?
解决Apollo MockedProvider模拟GraphQL文件上传的匹配问题
当使用apollo-upload-client结合MockedProvider模拟文件上传时,直接用File实例作为mock变量会出现No more mocked responses for the query警告——原因是Apollo会将上传的File对象转换为内部包装结构,导致mock中的File实例与实际请求变量无法通过严格相等匹配。
方案1:使用自定义匹配函数matchFn(推荐)
MockedProvider支持通过matchFn替代request对象,自定义请求匹配逻辑,无需依赖严格的实例相等。
修改mock代码如下:
export const importSuccessFile = new File( ['test'], 'test.txt', { type: 'text/plain' } ); export const importMock = { matchFn: async (operation) => { // 验证查询是否匹配目标mutation if (operation.query !== ImportDocument) { return false; } const { file } = operation.variables; // 验证文件的关键属性(可根据测试需求调整校验项) const isFileNameMatch = file.name === importSuccessFile.name; const isFileTypeMatch = file.type === importSuccessFile.type; // 可选:验证文件内容 const uploadedContent = await file.blob.text(); const mockContent = await importSuccessFile.text(); const isFileContentMatch = uploadedContent === mockContent; return isFileNameMatch && isFileTypeMatch && isFileContentMatch; }, result: { data: { import: { success: true, }, }, }, };
代码说明:
matchFn接收请求的operation参数,包含当前请求的query和variables- 先校验query是否为目标的
ImportDocument - 再对比文件的
name、type等属性,按需验证文件内容 - 由于读取blob内容是异步操作,
matchFn需定义为async函数,返回Promise<boolean>
方案2:模拟Apollo转换后的File结构
如果不想使用异步匹配,可以手动模拟Apollo转换后的File变量结构(不推荐,依赖内部实现,可能随版本变化失效):
export const importMock = { request: { query: ImportDocument, variables: { file: { name: 'test.txt', type: 'text/plain', blob: new Blob(['test'], { type: 'text/plain' }), lastModified: importSuccessFile.lastModified, // 其他属性可根据实际请求的变量结构补充 }, }, }, result: { data: { import: { success: true, }, }, }, };
内容的提问来源于stack exchange,提问作者Will Squire
相关产品推荐
相关产品推荐

