如何测试CacheProvider

时间:2018-07-02 15:54:16

标签: c# .net unit-testing moq fakeiteasy

我有一个Cache类,如下所示:

public class MyCache : ICacheProvider
{ 
    private readonly IMemoryCache _cache; 
    private readonly MemoryCacheOptions _options;
    private readonly ILogger<InMemoryCacheProvider> _logger;  

    public MyCache(IMemoryCache cache, MemoryCacheOptions options, ILogger<InMemoryCacheProvider> logger)
    {
      //Elided
    }

    public virtual void Set<T>(string key, T value, TimeSpan expiration) where T : class
    {  
        _cache.Set(key, value, expiration); 
    } 

    public virtual T Get<T>(string key) where T : class
    { 
        if (_cache.Get(key) is T result)
        { 
            return result; 
        }  
        return default(T);
    } 
    // removed some code for clarity
 }

ICacheProvider具有类似SetGet的方法。

那么我该如何测试该课程?我需要测试set方法是否实际上将某些东西设置为依赖。使用FakeitEasy,我可以执行以下操作:

    [Fact]
    public void SetTest()
    {
        var cache = A.Fake<MyCache>();
        var item = A.Fake<TestClass>();
        cache.Set("item", item);

        A.CallTo(() => cache.Set("item", item)).MustHaveHappened(); 
    }

但是这对我来说没有太大意义。

我感兴趣的是,当我调用set方法时,我需要能够检查假缓存中是否确实存在对象集或其他内容。与Get和其他方法相同。

您能详细说明吗?

1 个答案:

答案 0 :(得分:3)

@Nkosi的评论正确。通过模拟受测者的协作者来使用模拟框架。然后可以执行被测系统。像这样:

// mock a collaborator
var fakeCache = A.Fake<IMemoryCache>();

// Create a real system under test, using the fake collaborator.
// Depending on your circumstances, you might want real options and logger,
// or fake options and logger. For this example, it doesn't matter.
var myCacheProvider = new MyCache(fakeCache, optionsFromSomewhere, loggerFromSomewhere);

// exercise the system under test
myCacheProvider.Set("item", item, someExpriation);

// use the fake collaborator to verify that the system under test worked
// As @Nkosi points out, _cache.Set(key, value, expiration)
// from the question is an extension method, so you can't assert on it
// directly. Otherwise you could do
// A.CallTo(() => fakeCache.Set("item", item, expiration)).MustHaveHappened();
// Instead you'll need to assert on CreateEntry, which could be a little trickier