私有数组元素测试的复杂性

C#中,当尝试设置一个私有类型的私有数组的元素时,事情会变得复杂。想象一下这个假设的类来测试

public static class MyClass { private static readonly MyInnerClass[] myArray = new MyInnerClass[10]; public static bool IsEmpty() { foreach (var item in myArray) { if ((item != null) && (!string.IsNullOrEmpty(item.Field))) { return false; } } return true; } private class MyInnerClass { public string Field; } }

如果想写一个测试用例,当数组有“非空”条目时,需要先设置数组。使用Visual Studio生成的访问器,会这样写:

[TestClass()] public class MyClassTest { [TestMethod()] public void IsEmpty_NotEmpty_ReturnsFalse() { for (int i = 0; i < 10; i++) { MyClass_Accessor.myArray[i] = new MyClass_Accessor.MyInnerClass { Field = i.ToString() }; } bool expected = false; bool actual; actual = MyClass.IsEmpty(); Assert.AreEqual(expected, actual); } }

但是测试会失败,因为虽然可以作为MyClass_Accessor.MyInnerClass实例读取私有数组myArray的元素,但不能这样写入。要做到这一点,测试应该这样写:

[TestClass()] public class MyClassTest { [TestMethod()] public void IsEmpty_NotEmpty_ReturnsFalse() { for (int i = 0; i < 10; i++) { MyClass_Accessor.ShadowedType.SetStaticArrayElement( "myArray", new MyClass_Accessor.MyInnerClass { Field = i.ToString() }.Target, i); } bool expected = false; bool actual; actual = MyClass.IsEmpty(); Assert.AreEqual(expected, actual); } }

但是,这样就失去了访问器的所有强类型,因为需要写出数组字段的名称。由于字段的访问器是一个属性,可以编写一组扩展方法,为获取字段名称。类似这样:

public static class PrivateTypeExtensions { public static void SetStaticArrayElement( this PrivateType self, Expression> expression, T value, params int[] indices) { object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value; self.SetStaticArrayElement( ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name, elementValue, indices); } public static void SetStaticArrayElement( this PrivateType self, Expression> expression, BindingFlags invokeAttr, T value, params int[] indices) { object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value; self.SetStaticArrayElement( ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name, invokeAttr, elementValue, indices); } } [TestClass()] public class MyClassTest { [TestMethod()] public void IsEmpty_NotEmpty_ReturnsFalse() { for (int i = 0; i < 10; i++) { MyClass_Accessor.ShadowedType.SetStaticArrayElement(() => MyClass_Accessor.myArray, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }, i); } bool expected = false; bool actual; actual = MyClass.IsEmpty(); Assert.AreEqual(expected, actual); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485