我有一种情况,在 MS Dynamics Crm 中,它使用密封类和只读属性返回一些对象(我只能假设使用内部构造函数或内部属性集)。而且这些人不会从我可以使用的界面继承。显然,如果我可以控制这段代码,我将拥有更多的控制权,但因为它位于底层的 MS Dynamics 框架中,所以我有点卡住了。
我想模拟/覆盖的类称为AliasedValue。我想模拟它的原因是我试图模拟对动态的调用并想假装我正在返回一些别名值。
所以这是场景,我想创建一个 Dynamics 将返回的示例实体......像这样:
var new_entity = new Entity("new_entity")
{
Attributes = new AttributeCollection
{
{"new_name", "BR"},
{"createdon", DateTime.Now.AddDays(-1).Date},
{"new_field", "My field"},
{"new_contact", new AliasedValue {*****} }
}
};
所以我引用了一个“联系人”实体(实时返回为 AliasedValue)。在测试时,我想确保我的代码处理可能会在该字段中返回的某些值(例如,它知道如何处理别名值,并且如果没有返回链接的联系人,它就不会爆炸,等等)。
因此,如果您单击 AliasedValue 的链接,您会注意到属性是只读的……所以我无法设置测试数据……
接下来,我要创建自己的类并覆盖整个东西......但它是密封的......
最重要的是,正如您可能已经猜到的那样,Moq 不喜欢尝试模拟密封类。
我读过我需要购买一些“更好”的模拟框架来做到这一点,但我真的不想为了解决这件事而花一些额外的钱。
任何人都为我提供了一个很好的小解决方案来解决这个问题?
更新澄清
如何返回的示例如下。我有一项服务将被模拟以返回上述对象。或者它实际返回的是一个包含上述对象的集合。所以这就像这样:
var service = new Mock<IOrganizationService>();
service
.Setup(s => s.RetrieveMultiple(null))
.Returns(new EntityCollection (new List<Entity> {new_entity}));
太好了,我可以返回上面的实体并用它做我想做的事。因此,在我创建了上述实体并通过我的模拟服务返回它之后,我在我的“EntityCollection”中得到了上述内容。一旦我有了我的实体,我就可以按如下方式访问该属性:
var aliasedContact = (AliasedValue)new_entity.Attributes["new_contact"];
也许我很傻,但我不太明白答案(由 Lunivore 提供)将如何解决这个问题......(添加评论以获得反馈......)