我有一种情况,在MS Dynamics Crm中它使用密封类和只读属性(我只能假定使用内部构造函数或内部属性集)返回一些对象。而这些人不会从我可以使用的界面继承。很明显,如果我能控制这段代码,我会有更多的控制权,但是因为它在底层的MS Dynamics框架中,所以我有点卡住了。模拟(Moq)或覆盖密封类中的只读操作?
我想要模拟/覆盖的类叫做AliasedValue。我想嘲笑它的原因是我试图模拟对动态的调用,并想假装我得到一些别名的价值。
所以这里的情景,我想创建一个动态将返回一个样本实体......是这样的:
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)将如何解决这个...(添加评论以获得反馈...)
我想探索gonig下来若昂安杰洛路线在此之前有点...我已经编辑了原来的职位澄清。你能看看并告诉我你的想法吗? (另外,“clicky”这个词可能误导了你一个点!我的意思是它是“点击”这个词,即它是一个URL) – 2012-08-10 16:55:34
好的,所以阅读你想要做的事情,你需要包装OrganizationService ,Entity和EntityCollection和AliasedValue。它只有四个类,但是一旦你完成了它,你就可以在代码中的任何地方使用这些类。如果您有方便的GoF模式手册,请查看适配器模式。然后每个类都包含其真实的委托对象,或者(在模拟AliasedValueWrapper的情况下)您正在查找的测试数据。 – Lunivore 2012-08-10 17:04:21
好吧,让我在接受答案之前再次查看适配器模式。 (我经常使用这种模式,所以也许我今天只是有一个金发的时刻...) – 2012-08-10 17:07:31