如何测试Azure Blob中Magick.NET转换后的JPEG存储正确性?
如何验证PNG转JPEG后成功存储到Blob?
问题背景
我需要让应用支持接收任意图片格式,通过Magick.NET-Q8-AnyCPU 13.6.0将其转换为JPEG文件。现有实现代码如下:
var memStream = new MemoryStream(); if (contentType != "image/jpeg") { var convertedImageFile = new MagickImage(imageFile); convertedImageFile.Format = MagickFormat.Jpeg; convertedImageFile.Write(memStream); memStream.Position = 0; } var blobClient = containerClient.GetBlobClient(imageFileName); var headers = new BlobHttpHeaders { ContentType = "image/jpeg" }; await blobClient.UploadAsync(memStream, headers, metadata);
我编写了测试代码尝试验证转换后的JPEG是否正确存储,但测试失败:
// Arrange var fileName = "{filePath}/imageTestFile.png"; var containerClient = blobServiceClient.GetBlobContainerClient(); // Act /* 向端点发起请求并传入.png测试文件。 */ // Assert var blobClient = containerClient.GetBlobClient(imageId); var blobClientFile = await blobClient.OpenReadAsync(); var file = File.OpenRead(fileName); Assert.Equal(blobClientFile, file);
测试报错信息:
Assert.Equal() Failure: Values differ Expected: 11417 Actual: 33383
现在需要编写正确的测试,确认原PNG经上传转换为JPEG后已成功存储到Blob中。
解决方案
1. 核心问题分析
直接对比原PNG文件流和Blob中的JPEG流必然失败——两者格式不同,文件大小、字节内容完全不一致。你需要验证的是Blob中的文件是原PNG转换后的有效JPEG,且内容匹配,而非和原文件字节相等。
2. 正确的测试实现
步骤1:提前生成预期的JPEG基准文件
在测试初始化阶段,用和业务代码完全一致的Magick.NET逻辑把测试PNG转换成JPEG,作为验证的基准:
// Arrange var testPngPath = "{filePath}/imageTestFile.png"; var expectedJpegStream = new MemoryStream(); // 复用业务代码的转换逻辑生成预期JPEG using var originalImage = new MagickImage(testPngPath); originalImage.Format = MagickFormat.Jpeg; originalImage.Write(expectedJpegStream); expectedJpegStream.Position = 0; var containerClient = blobServiceClient.GetBlobContainerClient();
步骤2:执行上传后验证Blob内容
// Act /* 向端点发起请求并传入.png测试文件。 */ // Assert var blobClient = containerClient.GetBlobClient(imageId); var blobStream = await blobClient.OpenReadAsync(); // 第一步:验证Blob的ContentType确实是JPEG var blobProperties = await blobClient.GetPropertiesAsync(); Assert.Equal("image/jpeg", blobProperties.Value.ContentType); // 第二步:对比转换后的字节内容 using var blobMemoryStream = new MemoryStream(); await blobStream.CopyToAsync(blobMemoryStream); blobMemoryStream.Position = 0; // 对比基准JPEG和Blob中JPEG的字节数组 Assert.Equal(expectedJpegStream.ToArray(), blobMemoryStream.ToArray());
3. 更严格的视觉验证(可选)
如果担心JPEG压缩参数差异导致字节不匹配,可以对比图片的核心属性或像素哈希:
using var blobImage = new MagickImage(blobStream); using var expectedImage = new MagickImage(expectedJpegStream); // 验证图片宽高一致 Assert.Equal(expectedImage.Width, blobImage.Width); Assert.Equal(expectedImage.Height, blobImage.Height); // 验证像素哈希一致(忽略微小压缩差异) var expectedHash = expectedImage.Signature(); var blobHash = blobImage.Signature(); Assert.Equal(expectedHash, blobHash);
4. 修复业务代码的潜在漏洞
你的业务代码存在空流风险:如果传入的是JPEG文件,memStream会是空的,导致上传空文件。补充处理逻辑:
var memStream = new MemoryStream(); if (contentType != "image/jpeg") { var convertedImageFile = new MagickImage(imageFile); convertedImageFile.Format = MagickFormat.Jpeg; convertedImageFile.Write(memStream); memStream.Position = 0; } else { // 直接复制原JPEG到内存流 await imageFile.CopyToAsync(memStream); memStream.Position = 0; }
内容的提问来源于stack exchange,提问作者nathano
相关产品推荐
相关产品推荐

