如何让Mock每次调用都返回新的MemoryStream?
解决Mock接口时重复使用MemoryStream导致的流末尾问题
你当前的Mock Setup会在初始化时就创建一个MemoryStream实例,所有对ApiSupplierProductPostAsync的调用都会复用这个流对象。第一次读取后流的Position会移到末尾,第二次调用时自然无法读取到数据。
要解决这个问题,你需要让Setup每次被调用时都生成新的MemoryStream和FileResponse实例,可以通过Moq的ReturnsAsync重载方法,传入一个委托函数来实现:
_client.Setup(c => c.ApiSupplierProductPostAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) .ReturnsAsync(() => new FileResponse( 200, null, new MemoryStream(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(json))), null, null));
原理说明
- 原来的写法是直接创建
FileResponse实例并返回,这个实例里的MemoryStream是固定的; - 改用
ReturnsAsync(() => ...)后,每次调用ApiSupplierProductPostAsync时,都会执行委托里的代码,创建全新的MemoryStream和FileResponse,确保每次的流都是初始状态(Position在开头)。
如果需要根据传入的请求JSON动态生成响应内容,还可以在委托中接收方法参数:
_client.Setup(c => c.ApiSupplierProductPostAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) .ReturnsAsync((string requestJson, CancellationToken ct) => { // 这里可以根据requestJson生成对应的响应数据 var responseJson = GenerateResponse(requestJson); return new FileResponse( 200, null, new MemoryStream(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(responseJson))), null, null); });
内容的提问来源于stack exchange,提问作者Sebastiaan Haverkate
相关产品推荐
相关产品推荐

