2013-03-14 6 views
3

개체의 다양한 속성에 원하는 값이 있다고 주장 할 MSTest (VS 2012) 단위 테스트가 있습니다. 이를 수행 할 수있는 많은 방법이 있습니다. 그러나 주된 관심사는 새 속성이 객체에 추가되면 유닛 테스트를 업데이트하여 기대 한 값을 가지게하는지 간과하기 쉽습니다.단위 테스트에서 개체에 확인되지 않은 추가 속성 추가

내가 생각할 수있는 한 가지는 객체의 공개 속성을 열거하기 위해 리플렉션을 사용한 다음 단위 테스트에서 어떤 속성이 선언되었는지 추적하고 마지막에 속성을 확인하지 않았다고 주장하는 것입니다.

비슷한 사람이 이미 작성한 사람이 있습니까?

더 좋은 아이디어가 있습니까?

업데이트 : 나는 문제의 objedct가 다른 클래스/업데이트 해당 개체의 데이터를 일으킬 방법이 있습니다 데이터 전송 객체 같은 것을 지적한다. 이러한 클래스/메소드에 대한 테스트를 간과하여 쉽게 모든 객체의 속성을 고려할 수 있습니다. 객체를 마우스 오른쪽 버튼으로 클릭하고, 참조를 찾고, 코드를 검토하는 것보다 조금 더 강하게 (즉, 잊어 버리거나 간과 할 수없는) 것이 싶습니다. 예를 들어

:

public class Person { 
    public string FirstName; 
} 

public Person GetPerson() {} 

[TestMethod] 
public void GetPerson_ReturnsFilledInPerson() 
{ 
    var actual = target.GetPerson(); 
    Assert.IsNotNull(actual.FirstName); 
    // If somebody later adds LastName to Person, 
    // we want this unit test to fail until the LastName is checked too. 
} 

감사합니다,

+3

코드를 업데이트하기 전에 테스트를 업데이트 할 수 있도록 TDD를 연습 해보는 것이 이상적입니다. – levelnis

+2

테스트가 너무 많은 것 같아요. 클래스에 새로운 속성이 추가되지 않도록하려면 별도의 테스트가 필요합니다. 당신은 또한 코드 커버리지를 볼 수 있습니다 ... –

답변

1

당신이 요구 한 무슨 일이 부당하지 않습니다. 간단한 Domain 클래스에서 DTO 로의 매핑을 위해서는 Automapper와 같은 프레임 워크를 사용할 수 있습니다. 도메인 클래스 A가 dto ADto에 맵핑한다고 말하면 설정보다 컨벤션을 사용하여 속성을 매핑합니다. 프레임 워크는 또한 모든 매핑을 완료했는지 테스트하는 방법과 함께 제공됩니다. Mapper.AssertConfigurationIsValid();을 호출하면 Dto의 모든 속성이 도메인 클래스의 속성에 매핑되었는지 확인합니다 (동일한 속성 이름을 사용하여 코드의 함 또는 함축).

기본적으로 당신은 똑같은 일을하려고합니다. 그래서 이것은 매우 유효한 시나리오입니다. Automapper를 사용하지 않기로 결정했다고 가정 해 보겠습니다. 당신의 코드에 별도의 mapper이 없다고 추측하고 있습니다.이 경우 리플렉션을 사용하여 매퍼 클래스/코드를 테스트 할 수 있습니다. 나는 모든 DTO가 다른 IDto를 리턴하는 DeepCopy 메소드를 구현하는 비슷한 일을했다. 그러나 실제 유형을 호출 유형과 같게하려고합니다.

[Test] 
    public void DeepCopyReturnsSameTypeAsOriginal() 
    { 
     var iDtoType = typeof (IDto); 
     var allIDtoTypes = iDtoType.Assembly.GetTypes().Where(t => iDtoType.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract).ToList(); 

     foreach (var currentIDtoType in allIDtoTypes) 
     { 
      var instanceOfDtoType = (IDto)Activator.CreateInstance(currentIDtoType); 
      var deepCopyType = instanceOfDtoType.DeepCopy(); 
      Assert.AreEqual(instanceOfDtoType.GetType(), deepCopyType.GetType(), 
           string.Format("Deep Copy of Type '{0}' does not return the same Type. It returns '{1}'. The DeepCopy method of IDto should return the same type.", 
           instanceOfDtoType.GetType(), deepCopyType.GetType())); 
     } 
    } 

person 객체를 얻는 데 비슷한 논리를 사용할 수 있습니다. person 객체의 모든 public 속성을 가져 와서 반복하고 반환 한 구체 객체에 특정 속성에 대한 null이 아닌 값이 포함되어 있다고 주장하십시오.

그러나이 경우 테스트는 모든 속성이 널값이 아니어야한다는 것을 알고있는 매우 특정한 개체에만 사용해야합니다. 예를 들어 값 형식을 사용하면 AccountBalance 속성이 0을 반환하면 사람의 균형이 0입니까, 아니면 속성이 설정되지 않았습니까? 그 사람이 null 인 이메일 속성을 가지고 있다면 그것은 매핑되지 않았 음을 의미합니까 아니면 시스템에있는 사람의 이메일이 없습니다. 그래서 특정 매퍼 클래스를 사용하거나 Automapper를 사용하는 경우, "구체적으로 몇 가지 제한된 클래스로 작업 할 수 있습니다"라는 "가치가 있습니까"와는 달리 매핑이 존재하는지 테스트하는 것입니다.

또 다른 옵션은 null 일 수없고 사용자 지정 특성으로 매핑해야하는 속성을 데코 레이팅하는 것입니다.예를 들어,

Public class PersonDto { 
    [TestNotNull] 
    public string FirstName { get; set} 

} 

그런 다음 단위 테스트에서이 속성을 사용하여 리플렉션을 사용하여 모든 속성을 찾고 null이 아닌지 확인하십시오. 물론 다른 레벨에서 풀려고하는 것과 동일한 문제에 부딪치게됩니다. 사람들이 중요한 필드를 매핑하는 것을 잊어 버린다는 두려움이 있다면이 필드를 사용자 지정 특성으로 꾸미는 것을 잊지 못할 수도 있습니다.

물론, 속성이 매핑되고 있는지 테스트하고 싶지 않고 속성 만 존재하는지 테스트 할 수도 있습니다. 이 경우 리플렉션을 사용하여 도메인 객체 유형의 모든 속성 목록을 가져와 각각이 DTO 객체 유형의 속성 목록에 있는지 확인하십시오. 그러나 이것은 속성 자체가 매핑되고 있는지, 존재 하는지를 테스트하지 않습니다. Automapper와 AssertConfigurationIsValid() 테스트를 사용하는 경우 DTO의 각 속성이 DTO의 관련 속성을 갖지 않고 DTO의 각 속성이 올바르게 매핑되는지 테스트합니다.

질문에 대답하기 위해 속성이 존재하고 제대로 매핑되고 있는지 테스트하려면 두 가지 테스트가 필요합니다. 하나는 도메인 객체 유형을 Dto 객체 유형과 비교하고 다른 객체의 속성이 다른 객체에 존재하는지 확인하고 또 다른 테스트는 DTO의 모든 속성이 매핑에 있는지 여부에 관계없이 무언가에 매핑되는지 확인합니다. 자신의 코드 또는 Automapper와 같은 프레임 워크 사용).