You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确Mock BlobBaseClient.DownloadTo(Stream)方法?

问题解决方法

核心问题分析

你当前的代码存在两个关键问题:

  1. Mock的MemoryStream未写入任何内容,读取自然为空
  2. 误解了DownloadTo方法的工作逻辑——该方法的核心是将内容写入传入的流参数,而非依赖返回的Response对象的ContentStream(除非你的业务逻辑特殊定义)

修正方案一(推荐:使用真实流,贴近真实场景)

直接在DownloadTo的Setup中拦截传入的流,写入目标内容:

var xmlContent = @"<?xml version='1.0'?>test data</xml>";
var responseMock = new Mock<Response>();
// 按需设置Response的Content属性
responseMock.Setup(r => r.Content).Returns(new BinaryData(xmlContent));

// 关键:Setup DownloadTo时,向传入的流写入内容并重置位置
_blobClientMock.Setup(b => b.DownloadTo(It.IsAny<MemoryStream>()))
    .Callback<MemoryStream>(targetStream => 
    {
        var contentBytes = Encoding.UTF8.GetBytes(xmlContent);
        targetStream.Write(contentBytes, 0, contentBytes.Length);
        // 重置流位置到开头,确保后续读取能获取内容
        targetStream.Position = 0;
    })
    .Returns(responseMock.Object);

修正方案二(若必须Mock Stream)

如果业务场景要求必须MockMemoryStream,需要为Mock对象设置读取逻辑和位置属性:

var xmlContent = @"<?xml version='1.0'?>test data</xml>";
var contentBytes = Encoding.UTF8.GetBytes(xmlContent);
var streamMock = new Mock<MemoryStream>();

// 设置Mock Stream的Read行为,模拟内容读取
streamMock.Setup(s => s.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
    .Callback<byte[], int, int>((buffer, offset, count) => 
    {
        var bytesToCopy = Math.Min(count, contentBytes.Length - (int)streamMock.Object.Position);
        Array.Copy(contentBytes, (int)streamMock.Object.Position, buffer, offset, bytesToCopy);
        streamMock.Object.Position += bytesToCopy;
    })
    .Returns<int, int, int>((buffer, offset, count) => 
    {
        return Math.Min(count, contentBytes.Length - (int)streamMock.Object.Position);
    });

// 设置Position属性的可读写
streamMock.SetupProperty(s => s.Position, 0);

var responseMock = new Mock<Response>();
responseMock.Setup(r => r.Content).Returns(new BinaryData(xmlContent));
responseMock.Setup(r => r.ContentStream).Returns(streamMock.Object);

_blobClientMock.Setup(b => b.DownloadTo(It.IsAny<MemoryStream>())).Returns(responseMock.Object);

注意事项

  • 调用DownloadTo后,若要读取传入的流,必须确保流的Position重置为0,否则读取指针会停在流的末尾
  • 测试时优先使用真实的MemoryStream,Mock流仅用于特殊场景,避免不必要的复杂度

内容的提问来源于stack exchange,提问作者Miro Georgiev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 23:31:12