我有两个对象,这些对象的大多数属性具有相同的类型和名称,并且我有一个方法将对象A的值分配给对象B中的匹配属性。我正在编写一个单元测试,该调用应调用该方法,然后进行断言对于对象B中具有匹配属性的对象A中的每个属性,将复制该值。
我要完成此操作的想法是使用反射枚举对象A中的所有属性,然后为每个属性分配一个随机值。然后,我调用“复制值”方法以将值复制到对象B,然后使用反射来枚举每个对象上的字段,并确保具有匹配名称的字段具有相同的值。
这是我为对象A分配随机值的代码
var objectA = new ObjectA();
var random = new Random();
var fields = typeof(ObjectA).GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fields)
{
if (field.CanWrite)
{
if (field.PropertyType == typeof(bool) || field.PropertyType == typeof(bool?))
{
field.SetValue(objectA, Convert.ToBoolean(random.Next(2)));
}
if (field.PropertyType == typeof(decimal) || field.PropertyType == typeof(decimal?))
{
field.SetValue(objectA, Convert.ToDecimal(random.Next()));
}
if (field.PropertyType == typeof(string))
{
field.SetValue(objectA, random.Next().ToString());
}
// similar code for other data types
}
}
然后,我调用我的方法来复制值:
ObjectB objectB = ObjectB.FromObjectA(objectA);
然后,我调用此方法来比较两个对象的值:
public static void AssertMatchingFieldAreEqual<T1, T2>(T1 a, T2 b)
{
foreach (var fieldA in typeof(T1).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
var fieldInfoB = typeof(T2).GetProperty(fieldA.Name);
if (fieldInfoB != null)
{
var propertyA = typeof(T1).GetProperty(fieldA.Name);
var propertyB = typeof(T2).GetProperty(fieldA.Name);
// Adding field names to make error messages for failed Assert calls list the field name
var valueA = $"{propertyA.Name}: {propertyA.GetValue(a)}";
var valueB = $"{propertyB.Name}: {propertyB.GetValue(b)}";
Assert.AreEqual(valueA, valueB);
}
}
}
这适用于基本数据类型。我的问题是我有一些是List
s的字段,我想用它们的类型的随机数量的对象填充它们,然后断言在复制字段时,每个列表都具有相同数量的对象。
我的两个问题:
分配值时,如何在List
不知道列表中项目类型的情况下检查属性是否为?我已经尝试过了if (field.PropertyType == typeof(List<object>)
,但这不起作用。
T
当我的属性类型是列表时,如何创建类型为add并将其添加到列表的新对象?
或者,如果有更好的方法来检查我的“复制值”方法是否复制了所有相同名称的字段,还有什么更好的方法?
您问题的直接答案是,您需要将通用测试纳入您的反思中。
if(field.PropertyType.GetGenericTypeDefinition() == typeof(List<>)){
var typeOfThingInside = field.PropertyType.GetGenericArguments()[0];
// ...
}
更好的方法是使用AutoFixture创建对象,然后使用Fluent断言检查是否已复制所有内容。
void Main()
{
// Arrange
var fixture = new Fixture();
var a = fixture.Create<ObjectA>();
// Act
var b = ObjectB.FromObjectA(a);
// Assert
b.Should().BeEquivalentTo(a, options => options.ExcludingMissingMembers());
}
public class ObjectA {
public int A {get;set;}
public string B {get;set;}
public List<string> C {get;set;}
public decimal Z {get;set;}
}
public class ObjectB
{
public int A { get; set; }
public string B { get; set; }
public List<string> C { get; set; }
public decimal Y { get; set; }
public static ObjectB FromObjectA(ObjectA a) => JsonConvert.DeserializeObject<ObjectB>(JsonConvert.SerializeObject(a));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句