调用扩展方法的设置结果

问题描述 投票:15回答:3

我正在尝试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方法似乎存在问题,这是一种扩展方法。

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

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

c# unit-testing nunit moq
3个回答
25
投票

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

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


5
投票

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

而只是模拟Get对象的InsertCache方法。


1
投票

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

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);

请注意,此代码未经过测试,但应解释基本概念。

© www.soinside.com 2019 - 2024. All rights reserved.