I understand IMemoryCache.Set is an extension method so it can not be mocked. People have provided workarounds to such situation e.g as one by the NKosi here. I am wondering how I can achieve that for my data access layer where my MemoryCache returns a value and when not found it gets data from the db, set it to the MemoryCache and return the required value.
public string GetMessage(int code)
{
if(myMemoryCache.Get("Key") != null)
{
var messages= myMemoryCache.Get<IEnumerable<MyModel>>("Key");
return messages.Where(x => x.Code == code).FirstOrDefault().Message;
}
using (var connection = dbFactory.CreateConnection())
{
var cacheOptions = new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(1) };
const string sql = @"SELECT Code, Message FROM MyTable";
var keyPairValueData = connection.Query<KeyPairValueData>(sql);
myMemoryCache.Set("Key", keyPairValueData, cacheOptions );
return keyPairValueData.Where(x => x.Code == code).FirstOrDefault().Message;
}
}
Following is my Unit Test - And off course it is not working as I can't mock IMemoryCache
[Fact]
public void GetMessage_ReturnsString()
{
//Arrange
// Inserting some data here to the InMemoryDB
var memoryCacheMock = new Mock<IMemoryCache>();
//Act
var result = new DataService(dbConnectionFactoryMock.Object, memoryCacheMock.Object).GetMessage(1000);
//assert xunit
Assert.Equal("Some message", result);
}