0

I have a service class with some injected services. It's dealing with my Azure storage requests. I need to write NUnit tests for that class. I'm new to NUnit and I'm struggling with making the object of that my AzureService.cs

Below AzureService.cs. I have used some injected services

using System;
using System.Linq;
using System.Threading.Tasks;
using JohnMorris.Plugin.Image.Upload.Azure.Interfaces;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Nop.Core.Caching;
using Nop.Core.Configuration;
using Nop.Core.Domain.Media;
using Nop.Services.Logging;

namespace JohnMorris.Plugin.Image.Upload.Azure.Services
{
    public class AzureService : IAzureService
    {

        #region Constants

        private const string THUMB_EXISTS_KEY = "Nop.azure.thumb.exists-{0}";
        private const string THUMBS_PATTERN_KEY = "Nop.azure.thumb";

        #endregion

        #region Fields
        private readonly ILogger _logger;
        private static CloudBlobContainer _container;
        private readonly IStaticCacheManager _cacheManager;
        private readonly MediaSettings _mediaSettings;
        private readonly NopConfig _config;

        #endregion

        #region
        public AzureService(IStaticCacheManager cacheManager, MediaSettings mediaSettings, NopConfig config, ILogger logger)
        {
            this._cacheManager = cacheManager;
            this._mediaSettings = mediaSettings;
            this._config = config;
            this._logger = logger;
        }

        #endregion


        #region Utilities
        public string GetAzureStorageUrl()
        {
            return $"{_config.AzureBlobStorageEndPoint}{_config.AzureBlobStorageContainerName}";
        }

        public virtual async Task DeleteFileAsync(string prefix)
        {
            try
            {
                BlobContinuationToken continuationToken = null;
                do
                {                    
                    var resultSegment = await _container.ListBlobsSegmentedAsync(prefix, true, BlobListingDetails.All, null, continuationToken, null, null);

                   await Task.WhenAll(resultSegment.Results.Select(blobItem => ((CloudBlockBlob)blobItem).DeleteAsync()));

                    //get the continuation token.
                    continuationToken = resultSegment.ContinuationToken;
                }
                while (continuationToken != null);

                _cacheManager.RemoveByPrefix(THUMBS_PATTERN_KEY);
            }
            catch (Exception e)
            {
                _logger.Error($"Azure file delete error", e);
            }
        }


        public virtual async Task<bool> CheckFileExistsAsync(string filePath)
        {
            try
            {
                var key = string.Format(THUMB_EXISTS_KEY, filePath);
                return await _cacheManager.Get(key, async () =>
                {
                    //GetBlockBlobReference doesn't need to be async since it doesn't contact the server yet
                    var blockBlob = _container.GetBlockBlobReference(filePath);

                    return await blockBlob.ExistsAsync();
                });
            }
            catch { return false; }
        }

        public virtual async Task SaveFileAsync(string filePath, string mimeType, byte[] binary)
        {
            try
            {
                var blockBlob = _container.GetBlockBlobReference(filePath);

                if (!string.IsNullOrEmpty(mimeType))
                    blockBlob.Properties.ContentType = mimeType;

                if (!string.IsNullOrEmpty(_mediaSettings.AzureCacheControlHeader))
                    blockBlob.Properties.CacheControl = _mediaSettings.AzureCacheControlHeader;

                await blockBlob.UploadFromByteArrayAsync(binary, 0, binary.Length);

                _cacheManager.RemoveByPrefix(THUMBS_PATTERN_KEY);
            }
            catch (Exception e)
            {
                _logger.Error($"Azure file upload error", e);
            }
        }

        public virtual byte[] LoadFileFromAzure(string filePath)
        {
            try
            {
                var blob = _container.GetBlockBlobReference(filePath);
                if (blob.ExistsAsync().GetAwaiter().GetResult())
                {
                    blob.FetchAttributesAsync().GetAwaiter().GetResult();
                    var bytes = new byte[blob.Properties.Length];
                    blob.DownloadToByteArrayAsync(bytes, 0).GetAwaiter().GetResult();
                    return bytes;
                }
            }
            catch (Exception)
            {
            }
            return new byte[0];
        }
        #endregion
    }
}

This is my test class below, I need to create new AzureService(); from my service class. But in my AzureService constructor, I'm injecting some service

using JohnMorris.Plugin.Image.Upload.Azure.Services;
using Nop.Core.Caching;
using Nop.Core.Domain.Media;
using Nop.Services.Tests;
using NUnit.Framework;

namespace JohnMorris.Plugin.Image.Upload.Azure.Test
{
    public class AzureServiceTest 
    {
        private AzureService _azureService;

        [SetUp]
        public void Setup()
        {
               _azureService = new AzureService( cacheManager,  mediaSettings,  config,  logger);
        }      

        [Test]
        public void App_settings_has_azure_connection_details()
        {
           var url= _azureService.GetAzureStorageUrl();
            Assert.IsNotNull(url);
            Assert.IsNotEmpty(url);
        }

       [Test]
       public void Check_File_Exists_Async_test(){
           //To Do
       }

       [Test]
       public void Save_File_Async_Test()(){
           //To Do
       }

       [Test]
       public void Load_File_From_Azure_Test(){
           //To Do
       }
    }
}

1 Answer 1

1

Question is, what exactly do you want to test? If you want to test if NopConfig is properly reading values from AppSettings, then you do not have to test AzureService at all.

If you want to test that GetAzureStorageUrl method is working correctly, then you should mock your NopConfig dependency and focus on testing only AzureService methods like this:

using Moq;
using Nop.Core.Configuration;
using NUnit.Framework;

namespace NopTest
{
    public class AzureService
    {
        private readonly NopConfig _config;

        public AzureService(NopConfig config)
        {
            _config = config;
        }

        public string GetAzureStorageUrl()
        {
            return $"{_config.AzureBlobStorageEndPoint}{_config.AzureBlobStorageContainerName}";
        }
    }

    [TestFixture]
    public class NopTest
    {
        [Test]
        public void GetStorageUrlTest()
        {
            Mock<NopConfig> nopConfigMock = new Mock<NopConfig>();

            nopConfigMock.Setup(x => x.AzureBlobStorageEndPoint).Returns("https://www.example.com/");
            nopConfigMock.Setup(x => x.AzureBlobStorageContainerName).Returns("containername");

            AzureService azureService = new AzureService(nopConfigMock.Object);

            string azureStorageUrl = azureService.GetAzureStorageUrl();

            Assert.AreEqual("https://www.example.com/containername", azureStorageUrl);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

App_settings_has_azure_connection_details() is just a test query. I edited my question with more detils

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.