2010-02-26 6 views
1

WPF 응용 프로그램에 대한 단위 테스트를 작성하고 있습니다 (쓰려고 시도 중).IDataErrorInfo 비즈니스 객체의 단위 테스트 오류는 어떻게합니까?

IDataErrorInfo를 구현하기 위해 UI가 바인딩하는 비즈니스 객체로, 뷰 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 

고마워요!

답변

4

단위 테스트에서 수행 할 작업은 Name 값을 설정 한 다음 명시 적으로 오류를 확인하기 위해 인덱서를 호출하는 것입니다.

단위 테스트에서 PropertyChanged 이벤트를 후킹 할 수는 있지만, 테스트 메서드에 이벤트가 수신되었음을 알리고 호출해야한다는 점에서 의미가 있다고는 생각하지 않습니다. 어쨌든 인덱서.

+0

그래, 당신과 조엘 B 팬트의 접근 방식은 훌륭합니다. 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)]); 
    } 
} 
관련 문제