模拟扩展方法导致 System.NotSupportedException

Sha*_*ani 5 c# extension-methods moq mocking .net-core

我正在对使用该IMemoryCache接口的 ClientService 进行单元测试:

客户端服务.cs:

public string Foo()
{        
    //... code

    _memoryCache.Set("MyKey", "SomeValue", new TimeSpan(0, 0, 60));
}
Run Code Online (Sandbox Code Playgroud)

当我尝试模拟IMemoryCacheSet扩展名时:

AutoMock mock = AutoMock.GetLoose();

var memoryCacheMock = _mock.Mock<IMemoryCache>();

string value = string.Empty;

// Attempt #1:
memoryCacheMock
     .Setup(x => x.Set<string>(It.IsAny<object>(), It.IsAny<string>(), It.IsAny<TimeSpan>()))
     .Returns("");

// Attempt #2:
memoryCacheMock
    .Setup(x => x.Set(It.IsAny<object>(), It.IsAny<object>(), It.IsAny<TimeSpan>()))
    .Returns(new object());
Run Code Online (Sandbox Code Playgroud)

它抛出以下异常:

System.NotSupportedException:不支持的表达式:x => x.Set(It.IsAny(), It.IsAny(), It.IsAny()) 扩展方法(此处:CacheExtensions.Set)不能用于设置/验证前

这是命名空间的缓存扩展 Microsoft.Extensions.Caching.Memory

public static class CacheExtensions
{
   public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, TimeSpan absoluteExpirationRelativeToNow);
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*nny 15

扩展方法实际上是静态方法,不能使用moq. 您可以模拟的是扩展方法本身使用的方法......

在你的情况下Set使用CreateEntrywhich 是由定义的方法IMemoryCache,它可以被嘲笑。尝试这样的事情:

memoryCacheMock
    .Setup(x => x.CreateEntry(It.IsAny<object>()))
    .Returns(Mock.Of<ICacheEntry>);
Run Code Online (Sandbox Code Playgroud)

  • Get 方法怎么样?我假设它是 TryGetValue 方法? (2认同)