#c# #.net-core #xunit
#c# #.net-core #xunit
Вопрос:
У меня есть интерфейс, определенный как:
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);
}
}
Но я получаю такую ошибку при выполнении тестового примера:
В следующих параметрах конструктора не было совпадающих данных о приборах: IProfessorsDAL professorsDAL
Я обнаружил, что мне нужно что-то издеваться, но я не уверен, как это сделать. Кто-нибудь может высказать несколько идей о том, как это сделать правильно? Кроме того, эта логика верна, поскольку я могу правильно загружать файлы, используя конечную точку в контроллере. У меня есть строка подключения в моем appsettings.json
Комментарии:
1. вы вводите интерфейс в свой модульный тест. Я никогда этого не видел — я почти уверен, что вы не хотите этого делать. Ваш модульный тест должен создать экземпляр класса, который вы пытаетесь протестировать.
2. Итак, если я попытаюсь создать экземпляр класса, например
var service = new ProfessorsDAL();
, мне нужно передать объект конфигурации внутрь, как мне это сделать?3. вы бы создали макет этого. Мне действительно нравится
Moq
фреймворк4. Я использовал фреймворк Moq для создания этого:
var configuration = new Mock<IConfiguration>();
и попытался использовать тот же параметр as для создания экземпляра, но он говорит:cannot convert from 'Moq.Mock<Microsoft.Extensions.Configuration.IConfiguration>' to 'Microsoft.Extensions.Configuration.IConfiguration'
. Извините, я новичок в этом5.
var service = new ProfessorsDAL(configuration.Object)
Ответ №1:
Я смог решить свою проблему, используя этот фрагмент кода вместо того, чтобы вводить интерфейс в unittest:
var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var service = new ProfessorsMockDAL(config);
Я только что создал экземпляр класса с конфигурацией, которая создается с использованием appsettings.json в расположении тестового проекта.