使用IMemoryCache扩展方法的单元测试方法

时间:2020-02-21 10:29:42

标签: c# unit-testing moq asp.net-core-3.1

我正在尝试使用MSTest和Moq为使用IMemoryCache扩展方法的方法编写单元测试。情况:

public class ClassToTest
{        
  private IMemoryCache Cache { get; }

  public ClassToTest(IMemoryCache cache)
  {          
    Cache = cache;
  }

  public async Task<SomeType> MethodToTest(string key)
  {
    // Get is an extension method defined in Microsoft.Extensions.Caching.Memory
    var ci = Cache.Get<CachedItem<T>>(key);

    // Do stuff with cached item
  }
}

如何对此进行单元测试?

到目前为止,我尝试过:

[TestMethod]
public void TestMethodToTest()
{
  IServiceCollection services = new ServiceCollection();
  services.AddMemoryCache();

  var serviceProvider = services.BuildServiceProvider();
  var memoryCache = serviceProvider.GetService<IMemoryCache>();

  ClassToTest testClass = new ClassToTest(memoryCache);
}

这给我以下错误:“'IServiceCollection'不包含'AddMemoryCache'的定义,并且找不到可访问的扩展方法'AddMemoryCache'接受类型为'IServiceCollection'的第一个参数(您是否缺少using指令?还是程序集引用?)”。

有人知道如何对该方法进行单元测试吗?最好不更改方法本身。 有标准的方法吗? 任何帮助都可以申请。

1 个答案:

答案 0 :(得分:1)

我认为您必须修改ClassToTest。您可以拥有类型Func<string, CachedItem<T>>的属性,该属性被分配为在类的构造函数中使用扩展名:

public Func<string, CachedItem<T>> GetFromCache { get; set; }
public ClassToTest(IMemoryCache cache)
{          
    Cache = cache;
    GetFromCache = key => Cache.Get<CachedItem<T>>(key);
}

然后,当您要测试该类时,可以通过说出以下内容来覆盖该行为:

ClassToTest testClass = new ClassToTest(memoryCache);
testClass.GetFromCache = key => /* something else */;

通常来说,扩展方法仍然只是静态方法的语法糖,因此像ClassToTest这样使用扩展方法确实会引入依赖关系,并使代码更难单独测试。