我正在为WPF应用程序编写(尝试编写)单元测试。
UI绑定的业务对象实现IDataErrorInfo,这样当我在View xaml中设置ValidatesOnDataErrors = True时,只要调用绑定业务对象的setter,就会调用错误索引器(this [])。 那部分很棒。
现在,如果我从unitTest调用同一属性的setter,它永远不会调用错误索引器。如何强制在单元测试中评估IDataErrorInfo索引器?
仅用于说明,这是我的一个包含Name属性的简单错误索引器。设置'myObject.Name = string.Empty;'当我在单元测试中执行此操作时,会调用setter,而不是错误索引器。
public string Name
{
get { return _name; }
set
{
_name = value;
IsDirty = true;
OnPropertyChanged("Name");
}
}
#region IDataErrorInfo
public Dictionary<string, string> ErrorCollection;
public string this[string property]
{
get
{
string msg = null;
switch (property)
{
case "Name":
if (string.IsNullOrEmpty(Name))
msg = "ICU Name is required.";
else if (Name.Length < 4)
msg = "ICU Name must contain at least 4 characters.";
else if (_parent.Units.AsEnumerable().Count(u => u.Name == Name) > 1)
msg = Name + " already exists, please change to a different Name.";
break;
}
if (msg != null && !ErrorCollection.ContainsKey(property))
ErrorCollection.Add(property, msg);
if (msg == null && ErrorCollection.ContainsKey(property))
ErrorCollection.Remove(property);
return msg;
}
}
public string Error
{
get { return null; }
}
#endregion
谢谢!
答案 0 :(得分:6)
您需要自己挂钩PropertyChanged
事件,然后在调用处理程序时,使用属性名称调用索引器。或者不要挂钩事件并使用您正在测试的属性的名称调用索引器。
这就是.NET的作用。它使用属性名称调用索引器。
MyClass mc = new MyClass();
mc.Name = "abc";
string error = mc["Name"];
答案 1 :(得分:4)
我在单元测试中要做的是设置Name的值,然后显式调用索引器来检查错误。
您可以在单元测试中挂钩PropertyChanged事件,但我认为这没有意义,因为您必须以某种方式通知测试方法已收到事件,然后您必须调用无论如何,索引器。
答案 2 :(得分:0)
以下NUnit测试称为Name属性的索引器并验证错误消息。
[TestFixture]
public class MyClassTests
{
[TestCase("", "ICU Name is required.")]
[TestCase("A Valid Name", null)]
public void ValidationIcuNameIsRequired(string name, string expectedResult)
{
// Arrange
var systemUnderTest = new MyClass();
// Act
systemUnderTest.Name = name;
// Assert
Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
}
[TestCase("a", "ICU Name must contain at least 4 characters.")]
[TestCase("ab", "ICU Name must contain at least 4 characters.")]
[TestCase("abc", "ICU Name must contain at least 4 characters.")]
[TestCase("abcd", null)]
[TestCase("abcde", null)]
public void ValidationIcuNameLongerThanThreeCharacters(string name, string expectedResult)
{
// Arrange
var systemUnderTest = new MyClass();
// Act
systemUnderTest.Name = name;
// Assert
Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
}
[Test]
public void ValidationParentDoesNotExist()
{
// Arrange
var systemUnderTest = new MyClass();
string icuName = "TestName";
systemUnderTest.Parent.Units.Add(new Unit() {Name = icuName });
// Act
systemUnderTest.Name = icuName;
// Assert
Assert.AreEqual(icuName + " already exists, please change to a different Name.", systemUnderTest[nameof(systemUnderTest.Name)]);
}
}