Skip to content

Unit testing code using LazyCache

Alastair Crabtree edited this page Mar 4, 2018 · 3 revisions

To make testing easier and to follow SOLID principles your code should not depend on an instance of CachingService. Instead you should depend upon the interface IAppCache and use a dependency injection container to pass you an instance of CachingService at runtime.

If you want to unit test IAppCache you have three options

  • Use a real in memory cache - pass in new LazyCache.CachingService()
  • Use the built in mock - new MockCachingService() (See source)
  • Use a mocking library like Moq - new Mock()

Example unit test

Say you want to test an API controller that does some caching:

public class DbTimeController : Controller
{
    private readonly IAppCache cache;
    private readonly DbTimeContext dbContext;

    public DbTimeController(DbTimeContext context, IAppCache cache)
    {
        dbContext = context;
        this.cache = cache;
    }

    [HttpGet]
    [Route("api/dbtime")]
    public DbTimeEntity Get()
    {
        var cachedDatabaseTime = cache.GetOrAdd("DbTimeController.Get", () => dbContext.GeDbTime());
        return cachedDatabaseTime;
    }
}

Then you could test it like this (using NUnit as an example)

[Test]
public void Get_ShouldFetchTheTimeFromTheDatabase_WhenNotInTheCache()
{
    DbTimeEntity fakeEntity = new DbTimeEntity("2000-01-01");
    var fakeDatabaseContext = GetMyInMemoryDatabaseFake(fakeEntity);
    DbTimeController controllerUnderTest = new DbTimeController(fakeDatabaseContext, new MockCachingService());

    DbTimeEntity actual = controllerUnderTest.Get();

    Assert.NotNull(actual);
    Assert.AreEqual("2000-01-01", actual.ToString())
}