c# - 使用最小起订量的非虚拟成员的无效设置

标签 c# unit-testing testing moq

我正在 moqing 一个界面,它有:

Dictionary<string, object> InstanceVariables { get; set; }

我已经创建了一个新的接口(interface)模拟并尝试对其进行设置,以便它只返回一个随机字符串,如下所示:

_mockContext.SetupGet(m => m.InstanceVariables[It.IsAny<string>()]).Returns(@"c:\users\randomplace");

但是我好像报错了:

{"Invalid setup on a non-virtual (overridable in VB) member: m => m.InstanceVariables[It.IsAny<String>()]"}

这到底是什么意思?我正在模拟界面,所以这不应该成为问题吗?

谢谢

最佳答案

我反对它的原因有很多。首先,正如评论中所提到的,没有理由不能在这里使用真正的字典。 We shouldn't mock types that what we don't ownonly mock types we do own .
线路_mockContext.SetupGet(m => m.InstanceVariables[It.IsAny<string>()]).Returns(@"c:\users\randomplace");试图模拟 GetDictionary<T, T>正如@RB 所说,这不是 virtual ,因此你的错误。您可能正在模拟您的 界面,但那里的设置在.NET 字典中。

其次,海事组织,It.IsAny<string>()导致测试非常薄弱,因为它会响应任何字符串。构建类似的东西:

const string MyKey = "someKey";

var dictionary =  new Dictionary<string, object>();
dictionary.Add(MyKey, @"c:\users\randomplace");
_mockContext.Setup(m => m.InstanceVariables).Returns(dictionary);

var sut = new SomeObject(_mockContext.Object());
var result = sut.Act(MyKey);

// Verify

会更强大,因为如果正确的 key 被提供给/或由您的被测系统 (sut) 生成,字典只能响应路径。


就是说,如果您绝对必须模拟字典,出于问题中不明显的原因...那么您界面上的属性需要是字典的界面,IDictionary ,而不是具体类:

IDictionary<string, object> InstanceVariables { get; set; }

然后您可以通过以下方式创建字典模拟:

var dictionary = new Mock<IDictionary<string, object>>();
dictionary.SetupGet(d => d[It.IsAny<string>()]).Returns(@"c:\users\randomplace");

然后在上下文模拟上:

_mockContext.SetupGet(d => d.InstanceVariables).Returns(dictionary.Object);

为什么需要虚拟化?

Moq and other similar mocking frameworks can only mock interfaces, abstract methods/properties (on abstract classes) or virtual methods/properties on concrete classes.

This is because it generates a proxy that will implement the interface or create a derived class that overrides those overrideable methods in order to intercept calls.
Credit to @aqwert

关于c# - 使用最小起订量的非虚拟成员的无效设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37779176/

相关文章:

c# - JS操作页面后如何提取最终的HTML?

c# - 三元运算符字符串长度错误

c# - MonoDevelop 2.4.1 未在 Windows 7 上运行最终无法加载 glibsharpglue-2

ruby-on-rails - Rails 3.1、rspec、guard 和 spork 在 Windows 上真的很慢

testing - 如何停用 Clojure 测试中的日志?

c# - 多个数据库更新:

带有类型丰富的 Scala 测试

unit-testing - ReSharper 运行所有测试,而不是选择单个测试

android - 使用 MockWebServer 和 MockResponse 使用 Buffer body 测试 OkHttp

.net - 您创建 stub 的首选工具是什么?