Dies ist ein gültiger Test (obwohl ziemlich übereifrig) und ich mache ihn manchmal, um die Konstruktorlogik zu testen. Wie Laiv in den Kommentaren erwähnt hat, sollten Sie sich jedoch fragen, warum.
Wenn Ihr Konstruktor so aussieht:
public Person(Guid guid, DateTime dob)
{
this.Guid = guid;
this.Dob = dob;
}
Ist es sinnvoll zu testen, ob es wirft? Ob die Parameter richtig zugewiesen sind, kann ich verstehen, aber Ihr Test ist ziemlich übertrieben.
Wenn Ihr Test jedoch ungefähr so funktioniert:
public Person(Guid guid, DateTime dob)
{
if(guid == default(Guid)) throw new ArgumentException("Guid is invalid");
if(dob == default(DateTime)) throw new ArgumentException("Dob is invalid");
this.Guid = guid;
this.Dob = dob;
}
Dann wird Ihr Test relevanter (da Sie tatsächlich irgendwo im Code Ausnahmen auslösen).
Eine Sache würde ich sagen, im Allgemeinen ist es eine schlechte Praxis, viel Logik in Ihrem Konstruktor zu haben. Die grundlegende Validierung (wie die oben durchgeführten Null- / Standardprüfungen) ist in Ordnung. Aber wenn Sie eine Verbindung zu Datenbanken herstellen und Daten von jemandem laden, riecht Code dort wirklich ...
Wenn Ihr Konstruktor es wert ist, getestet zu werden (weil viel Logik vorhanden ist), stimmt aus diesem Grund möglicherweise etwas anderes nicht.
Sie werden mit ziemlicher Sicherheit andere Tests haben, die diese Klasse in Geschäftslogikebenen abdecken. Konstruktoren und Variablenzuweisungen werden mit ziemlicher Sicherheit eine vollständige Abdeckung durch diese Tests erhalten. Daher ist es möglicherweise sinnlos, spezifische Tests speziell für den Konstruktor hinzuzufügen. Nichts ist jedoch schwarzweiß und ich hätte nichts gegen diese Tests, wenn ich sie mit Code überprüfen würde - aber ich würde fragen, ob sie über die Tests an anderer Stelle in Ihrer Lösung hinaus einen Mehrwert bieten.
In Ihrem Beispiel:
public Person(Id id, DateTime dateOfBirth) :
base(id)
{
if (dateOfBirth == null)
throw new ArgumentNullException("Date of Birth");
elseif (dateOfBith < new DateTime(1900,01,01)
throw new ArgumentException("Date of Birth");
DateOfBirth = dateOfBirth;
}
Sie führen nicht nur eine Validierung durch, sondern rufen auch einen Basiskonstruktor auf. Für mich ist dies ein weiterer Grund für diese Tests, da die Konstruktor- / Validierungslogik jetzt auf zwei Klassen aufgeteilt ist, was die Sichtbarkeit verringert und das Risiko unerwarteter Änderungen erhöht.
TLDR
Diese Tests haben einen gewissen Wert, die Validierungs- / Zuweisungslogik wird jedoch wahrscheinlich von anderen Tests in Ihrer Lösung abgedeckt. Wenn diese Konstruktoren viel Logik enthalten, die erhebliche Tests erfordert, deutet dies darauf hin, dass dort ein unangenehmer Codegeruch lauert.