【发布时间】:2020-10-23 13:21:19
【问题描述】:
我有一个接口定义为:
public interface IProfessorsDAL
{
Task<(bool, string)> UploadToBlob(string filename, byte[] imageBuffer = null, Stream stream = null);
}
我已经将类定义为:
public class ProfessorsMockDAL : IProfessorsDAL
{
private readonly IConfiguration _configuration;
public ProfessorsMockDAL(IConfiguration configuration)
{
_configuration = configuration;
}
public static string stConnectionString { get; } = "AppSetting:StaConnectionString";
public async Task<(bool, string)> UploadToBlob(string filename, byte[] imageBuffer = null, Stream stream = null)
{
CloudStorageAccount storageAccount = null;
CloudBlobContainer cloudBlobContainer = null;
string storageConnectionString = _configuration[stConnectionString];
// Check whether the connection string can be parsed.
if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
{
try
{
// Create the CloudBlobClient that represents the Blob storage endpoint for the storage account.
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
// Create a container called 'uploadblob' and append a GUID value to it to make the name unique.
cloudBlobContainer = cloudBlobClient.GetContainerReference("uploadblob");
// Get a reference to the blob address, then upload the file to the blob.
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(filename);
if (imageBuffer != null)
{
// OPTION A: use imageBuffer (converted from memory stream)
await cloudBlockBlob.UploadFromByteArrayAsync(imageBuffer, 0, imageBuffer.Length);
}
else if (stream != null)
{
// OPTION B: pass in memory stream directly
await cloudBlockBlob.UploadFromStreamAsync(stream);
}
else
{
return (false, null);
}
return (true, cloudBlockBlob.SnapshotQualifiedStorageUri.PrimaryUri.ToString());
}
catch (StorageException ex)
{
return (false, null);
}
}
else
{
return (false, null);
}
}
我正在尝试为相同的内容编写一个 Xunit 测试用例:
public class UnitTest1
{
private readonly IProfessorsDAL _professorsDAL;
public UnitTest1(IProfessorsDAL professorsDAL)
{
_professorsDAL = professorsDAL;
}
[Fact]
public async Task UploadToBlob()
{
var fileMock = new Mock<IFormFile>();
//Setup mock file using a memory stream
var content = "Hello World from a Fake File";
var fileName = "test.pdf";
var ms = new MemoryStream();
var writer = new StreamWriter(ms);
writer.Write(content);
writer.Flush();
ms.Position = 0;
fileMock.Setup(_ => _.OpenReadStream()).Returns(ms);
fileMock.Setup(_ => _.FileName).Returns(fileName);
fileMock.Setup(_ => _.Length).Returns(ms.Length);
var file = fileMock.Object;
var uploadSuccess = false;
string uploadedUri = null;
using (var stream = file.OpenReadStream())
{
(uploadSuccess, uploadedUri) = await _professorsDAL.UploadToBlob(file.FileName, null, stream);
}
Assert.True(uploadSuccess);
}
}
但是我在执行测试用例时遇到了这样的错误:
以下构造函数参数没有匹配的夹具数据:IProfessorsDALprofessorsDAL
我发现我需要模拟一些东西,但我不确定如何。任何人都可以就如何正确地做到这一点提出一些想法吗? 此外,这个逻辑是正确的,因为我可以使用控制器中的端点正确上传文件。我的 appsettings.json 中有连接字符串
【问题讨论】:
-
您正在将一个接口注入到您的单元测试中。我从来没有见过——我很确定你不想那样做。您的单元测试应该实例化您要测试的类。
-
所以如果我尝试像
var service = new ProfessorsDAL();这样实例化类,我需要在里面传递配置对象,我该怎么做? -
你会创建一个模拟它。我真的很喜欢
Moq框架 -
我使用 Moq 框架来创建这个:
var configuration = new Mock<IConfiguration>();并尝试使用与实例化参数相同的参数,但它显示:cannot convert from 'Moq.Mock<Microsoft.Extensions.Configuration.IConfiguration>' to 'Microsoft.Extensions.Configuration.IConfiguration'。很抱歉我是新手 -
var service = new ProfessorsDAL(configuration.Object)