2010-02-26 2 views
1

Я пишу (пытаюсь написать) модульные тесты для приложения WPF.Как выполнить единичные ошибки тестирования в бизнес-объекте IDataErrorInfo?

Бизнес-объекты, которые пользовательский интерфейс связывает для реализации IDataErrorInfo, так что когда я устанавливаю ValidatesOnDataErrors = True в моем представлении xaml, индексатор ошибок (this []) вызывается в любое время, когда вызывается сеттер для связанного бизнес-объекта. Эта часть замечательная.

Теперь, если я вызываю установщик того же самого свойства из unitTest, он никогда не вызывает индексатор ошибок. Как заставить идентификатор 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 

Спасибо!

ответ

4

Что я буду делать в модульном тесте, чтобы установить значение имени, то явно вызвать индексатор для проверки ошибок.

Вы можете подключить событие PropertyChanged в модульном тесте, но я не думаю, что это имеет смысл, так как вам нужно как-то уведомить метод тестирования о том, что событие было получено, а затем вам нужно будет позвонить индексатор в любом случае.

+0

Да, как ваш, так и подход Джоэла Б Фанта работают отлично. Менее насмешливо, просто называя индексатор, а не подключая событие PropertyChanged. Спасибо всем. – Bob

5

Вам необходимо подключиться к событию PropertyChanged самостоятельно, а затем, когда вызывается обработчик, вызовите индексатор с именем свойства. Или не подключайтесь к событию и вызывайте индексатор с именем тестируемого вами свойства.

Вот, что делает .NET. Он вызывает индексатор с именами свойств.

MyClass mc = new MyClass(); 
mc.Name = "abc"; 
string error = mc["Name"]; 
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)]); 
    } 
} 
Смежные вопросы