【问题标题】:Unit testing method that uses IMemoryCache extension method使用 IMemoryCache 扩展方法的单元测试方法
【发布时间】:2020-02-21 10:29:42
【问题描述】:

我正在尝试使用 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' 的定义,并且找不到接受'IServiceCollection' 类型的第一个参数的可访问扩展方法'AddMemoryCache'(您是否缺少使用指令还是程序集参考?)”。

有人知道如何对这个方法进行单元测试吗?最好不改变方法本身。 有没有标准的方法来做到这一点? 任何帮助都会得到帮助。

【问题讨论】:

  • 您确定您有必要的参考资料来访问该扩展方法吗?您是否缺少using 指令或程序集引用?

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


【解决方案1】:

我认为你必须修改ClassToTest。您可以拥有一个 Func&lt;string, CachedItem&lt;T&gt;&gt; 类型的属性,该属性被分配以在您的类的构造函数中使用扩展:

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 这样使用它们会引入依赖关系,并使代码更难单独测试。

【讨论】:

  • 成功了。我必须修复函数(请接受编辑)。谢谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多