0

I have a controller with the definition:

public async Task<ResponseDto> MethodNameController(List<string> identifiers)
{
    if(!_cache.TryGetValue(key, out IDictonary<string, string> result))
    {
        result = await service.GetMethodService(activityContextObject, identifiers)
        var cacheEntryOptions = new MemoryCacheEntryOptions()
        .SetSlidingExpiration(TimeSpan.FromSeconds(80))
        .SetAbsoluteExpiration(TimeSpan.FromSeconds(120))
        .SetSize(1024);
        _cache.Set(key, result, cacheEntryOptions);
    }

    return new ResponseDto{ //ResponseDto Object split into many fields};
}

The constructor is as below

public Controller(serviceName, httpContextAccessor, IOptionsSnapshot_config, IMemoryCache)
{
    _serviceName = serviceName,
    _httpContextAccessor = httpContextAccessor,
    _config = IOptionsSnapshot_config
    _cache = IMemoryCache
}

I'm facing difficulty in unit testing this method. I followed this blog, this SO answer and many more trynig to replicate them in my scenario and failed. I tried passing regular memory cache object(because I'm unable to mock it) but invoking controller returns error slidingExpirationTime should be positive, current time set is 00:00:00 I'm unable to set the sliding expiration in test classes. Can anyone guide me to correct resources or tell me how I can test this method. I'm new to writing xUnit tests, so any help will be great(For learning moq etc).

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
Arpit Chinmay
  • 313
  • 5
  • 16
  • Your code shows the sliding expiration in the controller as hard-coded to 80 seconds. Why is it zero when running unit tests? – Eric J. Sep 20 '22 at 19:49
  • 1
    @EricJ. The memoryCache object passed from test class to MethodNameController constructor was not initialized and it was giving NullReferenceException. When I initialised it, it started giving slidingExpirationTime error. I figured out, it was because the DI wasn't working in test class. I have now resolved the issue by adding the service in test class constructor, creating the memoryCache service and passing it in the constructor. – Arpit Chinmay Sep 21 '22 at 12:00

1 Answers1

1

The easiest would be to mock it using some libraries, like AutoFixture, Moq.

Generally you mock interfaces as follows:

var fixture = new Fixture() //creates objects that has fine logic in creating objects
    .Customize(new AutoMoqCusotmization); // customize the fixture to automoq interfaces

var cacheMock = fixture.Create<Mock<IMemoryCache>>();
// use cacheMock.Setup method

another, simplier option would be to use directly Mock:

var cacheMock = new Mock<IMemoryCache>();
// use cacheMock.Setup method

If you can not use any of the above you can define dummy implmentation for the service, like:

internal class DummyMemoryCache : IMemoryCache 
{
    // implement interface
)

and use it in place of IMemoryCache.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69