Тестовый пример Xunit выдает ошибку, связанную с конструктором

#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 в расположении тестового проекта.