我遇到了我的工作中的一类,看起来像这样:使用例如创建模拟和匿名对象的混合Moq和AutoFixture?
public class MyObject
{
public int? A {get; set;}
public int? B {get; set;}
public int? C {get; set;}
public virtual int? GetSomeValue()
{
//simplified behavior:
return A ?? B ?? C;
}
}
的问题是,我有一些代码,访问A,B和C,并调用GetSomeValue()方法(现在,我会说这不是一个好设计,但有时候我的双手被捆绑;-))。我想创建一个这个对象的模拟,同时,A,B和C设置为一些值。所以,当我使用起订量为这样:
var m = new Mock<MyObject>() { DefaultValue = DefaultValue.Mock };
让我安装上GetSomeValue结果()方法,但所有属性都设置为null(使用安装程序设置所有的人()是相当繁琐的,因为真实对象是一个令人讨厌的数据对象,并且具有比上述简化示例更多的属性)。
因此在另一方面,使用AutoFixture这样的:
var fixture = new Fixture();
var anyMyObject = fixture.CreateAnonymous<MyObject>();
令我无以STUP到GetSomeValue()的调用方法的能力。
是否有任何方法将这两者结合起来,具有匿名值和设置调用结果的能力?
编辑
基于nemesv的回答,我得出了以下的实用方法(希望我这样做是正确):
public static Mock<T> AnonymousMock<T>() where T : class
{
var mock = new Mock<T>();
fixture.Customize<T>(c => c.FromFactory(() => mock.Object));
fixture.CreateAnonymous<T>();
fixture.Customizations.RemoveAt(0);
return mock;
}
这是一个很好的解决方案,特别是因为它涵盖了嵌套类型,但是,它是更普遍的嵌套类型,有没有什么办法来摆脱部分:T == typeof运算(的MyObject)| | t == typeof(MyParent)? 我想到的逻辑是这样的:“如果混合的嵌套类型是可嘲弄的,使其成为一个混合,否则使它成为一个匿名值”。 – 2012-02-19 12:30:15
是的,只需要用更一般的东西来替代谓词即可。 – 2012-02-19 12:50:24
谢谢!我尝试使用(t!= null &&!!..IsPrimitive &&(t.GetConstructors(BindingFlags.Public).Length!= 0 || t.GetConstructor(Type.EmptyTypes)!= null))的谓词上班!你能看到这里有什么遗漏吗?我会尽量给它一点测试,并尝试让你知道是否有任何事情发生。 – 2012-02-19 20:33:39