我的问题有点奇怪,我认为这不是Autofixture可以解决的问题,而是在这里;
我们有一个测试循环遍历程序集中的每个ICloneable
并尝试克隆它。目前我想要摆脱和替换一种可怕的Populate
方法。它检查每个属性的类型并根据它分配一个默认值(一个漂亮的,大的,if if语句)。
我遇到的问题是我不想维护Autofixture.Register
方法的特定列表,因为这比方法本身更加维护。
有什么想法吗?
感谢。
private void CheckAssemblyClones(Assembly entitiesAssembly)
{
foreach (Type entityType in entitiesAssembly.GetTypes()
.Where(t => t.GetInterfaces().Contains(typeof(ICloneable))
&& !t.IsAbstract
&& t.GetConstructor(Type.EmptyTypes) != null))
{
ICloneable original = Activator.CreateInstance(entityType) as ICloneable;
//Horrible method is used here to populate the object
//This is where I tried to add fixture.Create(original) but it
//doesn't like this original is an interface. If I use entityType
//directly it complains as there are interfaces within the class
//implementations that are later fulfilled using an IoC
PopulateProperties(original, true);
//Tried this, which fails because it is an ICloneable
//var fixture = new Fixture();
//original = fixture.Create(original);
MethodInfo cloneMethod = entityType.GetMethod("Clone", new Type[]
{
typeof(Boolean)
});
object clone = cloneMethod.Invoke(original, new object[]
{
true
});
}
}
private static PropertyInfo[] PopulateProperties(object obj, bool nest)
{
//var fixture = new Fixture();
var properties = obj.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
//Tried this but it failed due to PropertyInfo being an abstract class.
//var autoProp = fixture.Create(property);
//For every type set a default value for the property
}
return properties;
}
答案 0 :(得分:1)
听起来你正在尝试编写一个涵盖多种类型行为的基于约定的测试。这就是AutoFixture.Idioms的用途。
勾勒出一个可能的实现,你应该考虑定义一个派生自IdiomaticAssertion
的类:
public class CloneableAssertion : IdiomaticAssertion
{
private readonly ISpecimenBuilder builder;
public CloneableAssertion(ISpecimenBuilder builder)
{
if (builder == null)
throw new ArgumentNullException("builder");
this.builder = builder;
}
public override void Verify(Type type)
{
// Check if type is ICloneable before trying to create it.
// Return if it's not ICloneable.
// If this.builder is a standard Fixture object, the returned
// object will be populated with data, if possible.
var sut = (ICloneable)Create(type);
// Insert test against sut here...
}
private object Create(Type type)
{
return new SpecimenContext(this.builder).Resolve(type);
}
}
有关更全面的示例,请参阅AutoFixture.Idioms的源代码。最好的起点可能是WritablePropertyAssertion,它相当小而且简单。
也许您只是为了内部使用而实施ICloneable
,在这种情况下它很好,但是您应该知道它的使用是discouraged in public APIs:< / p>
我们建议不要在公共API中实现ICloneable