Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Test and IDistributedCache using azure redis

I have a working implementation of Azure Redis and .Net Core 2 using code very similar to what's described in this article

My question is, how do you instantiate an instance of the cache from a unit test class? I've looked through a number of resources and found nothing.

I need to be able to create an instance to instantiate a class such as

    public CacheManager(IDataManager dataservices, IDistributedCache cache)
    {
        _cache = cache;
        _dataservices = dataservices;
    }

The code in startup.cs uses ConfigureServices

            //Configure Redis Cache
        var redisconnection = Configuration.GetConnectionString("Redis");
        services.AddDistributedRedisCache(o => { o.Configuration = redisconnection; });

Maybe I need to add a package to the unit test project? How is this done?

like image 951
user2503078 Avatar asked Sep 14 '18 15:09

user2503078


3 Answers

I have used the Microsoft.Extensions.Caching.Distributed.MemoryDistributedCache class for unit testing. This is an in-memory implementation of IDistributedCache.

Here is a snippet of my unit testing code.

        [TestMethod]
        public void ExampleTestMethod()
        {
            var expectedData = new byte[] { 100, 200 };

            var opts = Options.Create<MemoryDistributedCacheOptions>(new MemoryDistributedCacheOptions());
            IDistributedCache cache1 = new MemoryDistributedCache(opts);
            cache1.Set("key1", expectedData);
            var cachedData = cache1.Get("key1");

            Assert.AreEqual(expectedData, cachedData);

           //Use the variable cache as an input to any class which expects IDistributedCache
        }

In my example, I am on .NET Core 3.1 and the relevant NUGET packages are

    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.4" />

like image 183
Sau001 Avatar answered Nov 15 '22 04:11

Sau001


You could just mock the interfaces to behave as needed for the isolated unit test.

public void Test_CacheManager() {
    //Arrange
    IDataManager dataservices = new Mock<IDataManager>(); 
    IDistributedCache cache = new Mock<IDistributedCache>();
    var subject = new CacheManager(dataservices.Object, cache.Object);

    //Setup the mocks to behave as expected.

    //Act
    //...call the method under test

    //Assert
    //...assert the expected behavior
}

The above example uses Moq in order to demonstrate how to mock instances of the dependencies of the class under test.

Reference Moq Quickstart to get a better understanding of how to use the mocking library.

If you are connecting to an actual redis connection then this will no longer be a unit test but an integration test, which would require a completely different approach.

public void Test_CacheManager() {
    //Arrange

    IDataManager dataservices = new Mock<IDataManager>(); 
     //Setup the mocks to behave as expected.

    //Configure Redis Cache
    var services = new ServiceCollection();
    var redisconnection = "...";
    services.AddDistributedRedisCache(o => { o.Configuration = redisconnection; });
    var provider = services.BuildServiceProvider();
    IDistributedCache cache = provider.GetService<IDistributedCache>();

    var subject = new CacheManager(dataservices.Object, cache);

    //Act
    //...call the method under test

    //Assert
    //...assert the expected behavior
}
like image 44
Nkosi Avatar answered Nov 15 '22 05:11

Nkosi


This how i managed to do that in .net core 2.0 and 3.1. You need to use MemoryDistributedCache. And pass it through your service constructor. Your service in a real word uses IDistributedCache by depedency injection. MemoryDistributedCache also implements IDistributedCache.

var mockedCacheSettings = new Mock<IOptions<CacheSettings>>();

        var options = new OptionsWrapper<MemoryDistributedCacheOptions>(new MemoryDistributedCacheOptions());
        _memoryDistributedCache = new MemoryDistributedCache(options);
        _distributedCacheService = new DistributedCacheService(_memoryDistributedCache, mockedCacheSettings.Object, NullLogger<DistributedCacheService>.Instance);
like image 35
peyman gilmour Avatar answered Nov 15 '22 04:11

peyman gilmour