โดเมนของฉันประกอบด้วยคลาสที่ไม่เปลี่ยนรูปแบบง่าย ๆ มากมายเช่นนี้
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 # เพื่อรองรับประเภทอ้างอิงที่ไม่สามารถเปลี่ยนแปลงได้และไม่เป็นโมฆะ แต่ฉันจะทำอย่างไรเพื่อปรับปรุงสถานการณ์ในขณะเดียวกัน? มันคุ้มค่าที่จะเขียนแบบทดสอบทั้งหมดเหรอ? จะเป็นการดีหรือไม่ที่จะเขียนตัวสร้างรหัสสำหรับคลาสดังกล่าวเพื่อหลีกเลี่ยงการเขียนการทดสอบสำหรับแต่ละรายการ?
นี่คือสิ่งที่ฉันมีตอนนี้ตามคำตอบ
ฉันสามารถทำให้การตรวจสอบว่างและการเริ่มต้นคุณสมบัติง่ายขึ้นเพื่อให้มีลักษณะเช่นนี้:
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
จาก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());
}