如何使用Moq(C#)模拟BlobContainerClient.GetAppendBlobClient与AppendBlobClient.AppendBlockAsync
使用Moq模拟Azure.Storage.Blobs的Blob操作
前置准备
确保项目已安装以下NuGet包:
MoqAzure.Storage.BlobsNewtonsoft.Json(若用到JSON序列化)
模拟实现步骤
需要分两步完成模拟:先定义AppendBlobClient的核心方法行为,再让BlobContainerClient的GetAppendBlobClient返回这个模拟实例。
1. 模拟AppendBlobClient
创建AppendBlobClient的Mock对象,配置CreateIfNotExistsAsync和AppendBlockAsync的预期行为:
// 初始化AppendBlobClient的Mock实例 var mockAppendBlobClient = new Mock<AppendBlobClient>(); // 模拟CreateIfNotExistsAsync,返回成功响应 mockAppendBlobClient .Setup(client => client.CreateIfNotExistsAsync(It.IsAny<CancellationToken>())) .ReturnsAsync(Response.FromValue(true, Mock.Of<Response>())); // 模拟AppendBlockAsync,接受任意Stream参数并返回成功的BlobAppendInfo响应 mockAppendBlobClient .Setup(client => client.AppendBlockAsync( It.IsAny<Stream>(), It.IsAny<HttpRange>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<IProgress<long>>(), It.IsAny<CancellationToken>())) .ReturnsAsync(Response.FromValue(Mock.Of<BlobAppendInfo>(), Mock.Of<Response>()));
2. 模拟BlobContainerClient
创建BlobContainerClient的Mock对象,让其GetAppendBlobClient方法返回我们预先模拟好的AppendBlobClient实例:
// 初始化BlobContainerClient的Mock实例 var mockContainerClient = new Mock<BlobContainerClient>(); // 配置GetAppendBlobClient:当传入指定文件名时返回模拟的AppendBlobClient mockContainerClient .Setup(container => container.GetAppendBlobClient(It.Is<string>(name => name == "someFileName"))) .Returns(mockAppendBlobClient.Object);
3. 验证调用(可选)
若要确认目标方法是否被正确调用,可在测试逻辑结束后添加验证断言:
// 验证CreateIfNotExistsAsync被调用过一次 mockAppendBlobClient.Verify(client => client.CreateIfNotExistsAsync(It.IsAny<CancellationToken>()), Times.Once); // 验证AppendBlockAsync被调用过一次,且传入的Stream内容符合预期 mockAppendBlobClient.Verify(client => client.AppendBlockAsync( It.Is<Stream>(stream => { stream.Position = 0; var actualContent = new StreamReader(stream).ReadToEnd(); var expectedContent = JsonConvert.SerializeObject(someObject); return actualContent == expectedContent; }), It.IsAny<HttpRange>(), It.IsAny<IDictionary<string, string>>(), It.IsAny<IProgress<long>>(), It.IsAny<CancellationToken>()), Times.Once);
注意事项
- 模拟Azure SDK异步方法时,需用
ReturnsAsync返回符合接口要求的Response对象,可通过Response.FromValue快速创建模拟响应。 - 若需要精准匹配参数,用
It.Is<T>(condition)替代It.IsAny<T>,保证模拟逻辑的准确性。
内容的提问来源于stack exchange,提问作者noel
相关产品推荐
相关产品推荐

