0

I'm writing a unit test and therefore i need to fake an IMemoryCache.

public MyUseCaseTest()
{
  this.myCache = A.Fake<IMyCache>();
}

When i run the test and the tested method is called, the memory cache is checked if there is already an entry inside. Right now the .Get() for this memory cache is returning a default value, although nothing was added to the cache before.

Can anybody tell me if this is an expected behavior or if i'm doing something wrong. I know i can fake the call for .Get() as well, but i'm interested in why there is an object returned.

Current implementation of the cache looks like this.

public class MyCache : IMyCache
{
    private readonly ILogger<AppUserCompanyCache> logger;
    private readonly IMemoryCache memoryCache;

    public MyCache(ILogger<MyCache> logger)
    {
        this.logger = logger;
        this.memoryCache = new MemoryCache(new MemoryCacheOptions());
    }

    public MyModel? Get(Guid key)
    {
        try
        {
            this.memoryCache.TryGetValue(key, out MyModel myModel);
            return myModel;
        }
        catch (Exception)
        {
            this.logger.LogError("Failed to get value from cache!");
            return null;
        }
    }

    public void Set(Guid key, MyModel myModel)
    {
        try
        {
            if (this.Get(key) != null)
            {
                return;
            }

            var cacheEntryOptions = new MemoryCacheEntryOptions()
                .SetSlidingExpiration(TimeSpan.FromSeconds(5));

            this.memoryCache.Set(key, myModel, cacheEntryOptions);
        }
        catch (Exception)
        {
            this.logger.LogError("Failed to set value to cache!");
        }
    }
}
Thomas Meinhart
  • 659
  • 2
  • 7
  • 28
  • 2
    You already get a fake from `A.Fake` so I don't see why MyCache is relevant, and yes it is default behavior for FakeItEasy to return default value from fake methods. https://fakeiteasy.readthedocs.io/en/stable/default-fake-behavior/ – tia Jun 20 '22 at 07:00
  • It is expected behavior for a faked memorycache to return a value for ```Get()``` any key, even there where no models set before? – Thomas Meinhart Jun 20 '22 at 07:14
  • 3
    It is how FakeItEasy create fake in general. It cannot magically realize what kind of behaviour it should implement for each specific type. – tia Jun 20 '22 at 07:16

1 Answers1

4

Can anybody tell me if this is an expected behavior

Yes, it is. That's probably the biggest behavior difference between FakeItEasy and e.g. Moq: while Moq just returns null by default, FakeItEasy returns a dummy (this default behavior is described here). Most of the time, this is more convenient and makes the test "arrange" phase shorter. In this specific case, it's not what you want, but you can override it:

A.CallTo(() => this.myCache.Get(A<Guid>._)).Returns(null);
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758