semanticcomparison을 사용하여 중첩 된 오브젝트 속성을 비교합니다
-
21-12-2019 - |
문제
동일한 유형의 두 개의 객체를 회원의 두 개의 객체를 비교 해야하는 장치 테스트를 작성합니다. SemanticCompaRison 라이브러리를 사용하여 사용자 지정 비교 코드를 작성하지 않고이 작업을 처리하기로 결정했습니다. 평면 객체를 비교할 때 실제로 잘 작동합니다. 객체에도 비교 해야하는 중첩 된 객체가 포함되어있을 때 문제가 있습니다.
public class Outer
{
public string Name { get; set; }
public Inner Inner { get; set; }
}
public class Inner
{
public string Name { get; set; }
public string Value { get; set; }
}
public class Service
{
public Outer Method()
{
return new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}
};
}
}
.
내부 객체가 참조로 비교되기 때문에 이는 작동하지 않습니다.
[Test]
public void SimpleTest1()
{
// setup
var expectedLikeness = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}
}.AsSource().OfLikeness<Outer>();
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
.
작동을 작동 시키려면 중첩 된 객체의 프록시를 만들어 기본 equals 구현을 겹쳐 쓸 수 있습니다.
[Test]
public void SimpleTest2()
{
// setup
var expectedLikeness = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value1"
}.AsSource().OfLikeness<Inner>().CreateProxy()
}.AsSource().OfLikeness<Outer>();
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
.
잘 작동하지만 일부 서비스 코드 리팩토링 후에 우리는 내부 클래스의 값 속성이 예상 값과 다른 버그를 소개한다고 상상합니다. SemanticComparison의 멋진 기능은 불평등을 일으키는 구성원의 이름을 기록 할 수 있다는 것입니다. 그러나이 경우, 내부 클래스의 특정 속성의 이름이 아닌 "내부"가 불일치로 반환됩니다.
뭔가를 놓치고 있습니까? 실제 불일치 멤버를 반환 할 수 있도록 구성 할 수 있습니까?
이 예에서와 같이 간단한 데이터 구조에 대한 문제는 분명하지만 실제 코드를 테스트하기위한 불편 함이있을 수 있습니다.
해결책
아무도 대답하지 않았으므로 내 답변을 제공 할 것입니다.
그래서 추가 코드를 작성하지 않으면 ootb를 할 수없는 것 같습니다. 코드를 확장 메소드 세트에 래핑했습니다. 이러한 메소드에서는 참조가 아닌 내부 형상 / 수집 속성을 비교 해야하는 내부 등록 정보 / 수집 속성을 지정할 수 있습니다. 수동으로 프록시를 만들 필요가 없으면 모든 것이 내부적으로 이러한 확장 프로그램으로 처리됩니다. 모든 내부 비교의 결과가 기록되므로 구성원이 무효 값이 있는지 정확히 볼 수 있습니다.
여기에 "InnerLikeness"확장 방법 사용이 사용되는 문제의 테스트가 있습니다.
[Test]
public void ServiceTest3()
{
// setup
var expected = new Outer()
{
Name = "outerName",
Inner = new Inner()
{
Name = "innerName",
Value = "value2"
}
};
var expectedLikeness = expected.AsSource().OfLikeness<Outer>()
.WithInnerLikeness(d => d.Inner, s => s.Inner)
;
var sut = new Service();
// exercise sut
var actual = sut.Method();
// verify
expectedLikeness.ShouldEqual(actual);
}
.
내부 오브젝트의 값 속성이 일치하지 않으므로 테스트가 실패해야합니다. 출력에서 다음 메시지와 함께 실패합니다.
Comparing inner properties using likeness. Source: s => s.Inner Destination: d => d.Inner.
The source and destination values are not equal. Details: The provided value ClassLibrary1.Inner did not match the expected value ClassLibrary1.Inner. The following members did not match:
- Value.
Ploeh.SemanticComparison.LikenessException : The provided value ClassLibrary1.Outer did not match the expected value ClassLibrary1.Outer. The following members did not match:
- Inner.
.
소스 코드와 GitHub에서 더 많은 예를 찾을 수 있습니다.