如何为测试设置CloudBlob对象BlobProperties的LastModified属性
方案1:使用反射直接构造带指定LastModified的BlobProperties实例
无需修改现有业务代码,仅在单元测试中通过反射给私有字段赋值即可,适配Microsoft.Azure.Storage.Blob 11.2.2版本的代码如下:
// 构造BlobProperties实例 var blobProps = new BlobProperties(); // 获取LastModified属性对应的私有backing字段 var lastModifiedField = typeof(BlobProperties) .GetField("<LastModified>k__BackingField", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); // 赋值为自定义的时间值 lastModifiedField.SetValue(blobProps, (DateTimeOffset?)DateTimeOffset.Now); // 赋值给Mock的CloudBlockBlob即可 var blobMock = new Moq.Mock<CloudBlockBlob>(new Uri("https://fake-account.blob.core.windows.net/fake-container/fake-blob")); blobMock.Setup(b => b.Properties).Returns(blobProps);
如果字段名不匹配,可以在调试时通过typeof(BlobProperties).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)遍历所有私有字段,找到对应LastModified的存储字段即可。
方案2:引入抽象层解耦(长期更推荐)
直接依赖第三方SDK的密封类本身就会带来测试难、升级难的问题,你可以在业务逻辑和Azure SDK之间加一层薄抽象,彻底避免测试时和SDK密封类打交道:
- 定义抽象接口,声明你需要用到的Blob属性
public interface IBlobMetadata { DateTimeOffset? LastModified { get; } // 其他需要用到的Blob属性均可在此声明 }
- 实现Azure SDK的适配层
public class AzureBlobMetadataAdapter : IBlobMetadata { private readonly BlobProperties _sdkProps; public AzureBlobMetadataAdapter(BlobProperties sdkProps) { _sdkProps = sdkProps ?? throw new ArgumentNullException(nameof(sdkProps)); } public DateTimeOffset? LastModified => _sdkProps.LastModified; }
- 业务代码改为依赖
IBlobMetadata接口,测试时直接Mock接口即可,无需接触SDK的密封类:
// 测试代码示例 var mockMeta = new Moq.Mock<IBlobMetadata>(); mockMeta.Setup(m => m.LastModified).Returns(DateTimeOffset.Now); // 直接将mockMeta.Object传入你的业务逻辑即可
该方案的额外优势是后续如果要升级Azure SDK版本,仅需要修改适配层代码,业务逻辑和测试代码完全不受影响。
内容的提问来源于stack exchange,提问作者E. Pratt
相关产品推荐
相关产品推荐

