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?
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" />
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
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With