내 도메인은 다음과 같은 간단한 불변 클래스로 구성됩니다.
public class Person
{
public string FullName { get; }
public string NameAtBirth { get; }
public string TaxId { get; }
public PhoneNumber PhoneNumber { get; }
public Address Address { get; }
public Person(
string fullName,
string nameAtBirth,
string taxId,
PhoneNumber phoneNumber,
Address address)
{
if (fullName == null)
throw new ArgumentNullException(nameof(fullName));
if (nameAtBirth == null)
throw new ArgumentNullException(nameof(nameAtBirth));
if (taxId == null)
throw new ArgumentNullException(nameof(taxId));
if (phoneNumber == null)
throw new ArgumentNullException(nameof(phoneNumber));
if (address == null)
throw new ArgumentNullException(nameof(address));
FullName = fullName;
NameAtBirth = nameAtBirth;
TaxId = taxId;
PhoneNumber = phoneNumber;
Address = address;
}
}
null 검사와 속성 초기화를 작성하는 것은 이미 매우 지루하지만 현재 는 각 클래스에 대한 단위 테스트 를 작성 하여 인수 유효성 검사가 올바르게 작동하고 모든 속성이 초기화되었는지 확인합니다. 이것은 유익하지 않은 혜택으로 극도로 지루한 바쁜 일과 같습니다.
실제 솔루션은 C #이 기본적으로 불변성과 null이 아닌 참조 유형을 지원하는 것입니다. 그러나 그 동안 상황을 개선하기 위해 어떻게해야합니까? 이 모든 테스트를 쓸 가치가 있습니까? 각 클래스에 대한 테스트 작성을 피하기 위해 해당 클래스에 대한 코드 생성기를 작성하는 것이 좋은 생각입니까?
여기에 내가 대답을 바탕으로 한 것이 있습니다.
null 확인 및 속성 초기화를 단순화하여 다음과 같이 할 수 있습니다.
FullName = fullName.ThrowIfNull(nameof(fullName));
NameAtBirth = nameAtBirth.ThrowIfNull(nameof(nameAtBirth));
TaxId = taxId.ThrowIfNull(nameof(taxId));
PhoneNumber = phoneNumber.ThrowIfNull(nameof(phoneNumber));
Address = address.ThrowIfNull(nameof(address));
Robert Harvey 의 다음 구현 사용 :
public static class ArgumentValidationExtensions
{
public static T ThrowIfNull<T>(this T o, string paramName) where T : class
{
if (o == null)
throw new ArgumentNullException(paramName);
return o;
}
}
GuardClauseAssertion
from을 사용하여 null 검사를 테스트하는 것은 쉽습니다 AutoFixture.Idioms
( Esben Skov Pedersen 제안에 감사드립니다 ).
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(Address).GetConstructors());
이것은 더 압축 될 수 있습니다 :
typeof(Address).ShouldNotAcceptNullConstructorArguments();
이 확장 방법을 사용하여 :
public static void ShouldNotAcceptNullConstructorArguments(this Type type)
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(type.GetConstructors());
}