调用分机方法的设置结果

本文关键字:设置 结果 方法 调用 | 更新日期: 2023-09-27 18:35:07

我正在尝试Setup对扩展方法的调用的返回,并且正在接收:

SetUp : System.NotSupportedException : Expression references a method that does not belong to the mocked object: m => m.Cache.GetOrStore<String>("CacheKey", () => "Foo", 900)

Cache 对象(一种扩展方法)上引用 GetOrStore 方法似乎存在问题。

代码编译,但测试失败,出现此异常。

我需要做什么来设置这样的扩展方法的结果?

调用分机方法的设置结果

扩展方法不能像实例方法那样被模拟,因为它们不是在模拟类型上定义的。它们在其他静态类中定义。由于您不能简单地模拟这些,因此您应该模拟扩展方法使用的所有方法/属性。

这是扩展方法如何将代码紧密耦合到其他类的示例。无论你做什么,你的类都依赖于这些静态方法。你不能模拟它并孤立地测试它。如果里面有任何逻辑,我建议重构你的代码,将这些方法移动到它们自己的类中。

Moq 无法模拟静态方法,因此您将无法模拟GetOrStore扩展。

而只是模拟Cache对象的GetInsert方法。

这是可能的,虽然不漂亮...我假设您的扩展方法中有一些内部缓存对象,或者对某处某个缓存的引用。可以使用反射替换内部对象来存储缓存。你在测试中得到这样的东西:

IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());
Mock<ICache> internalCache = new Mock<ICache>();
internalCache.Setup(i => i.Get<String>("CacheKey")).Returns("Foo");
var cacheExtension = typeof(CacheExtensions);
var inst = cacheExtension.GetField("_internalCache", BindingFlags.NonPublic | BindingFlags.Static);
inst.SetValue(cacheExtension, internalCache.Object);

请注意,此代码未经过测试,但它应该解释基本思想。