Testen in C# (.NET): Überblick über Frameworks und Tools
Qualitatives Testen ist die Grundlage zuverlässiger Software auf der .NET-Plattform. Im C#-Ökosystem gibt es mehrere ausgereifte Frameworks für Modul- (Unit-), Integrations- und Abnahmetests. In diesem Artikel betrachten wir die wichtigsten Tools, ihre Besonderheiten und geben praktische Codebeispiele.
Wichtige Frameworks für Unit-Tests
In .NET Core und .NET 5+ ist die integrierte Testunterstützung durch drei Hauptframeworks realisiert:
- MSTest — das klassische Framework von Microsoft, einfach für Anfänger.
- NUnit — ein beliebtes Open-Source-Framework mit einer umfangreichen Sammlung von Attributen.
- xUnit.net — ein modernes, leichtes und flexibles Tool, erstellt vom Autor von NUnit.
Alle drei werden in Visual Studio, Rider und über die dotnet CLI unterstützt. Die Wahl hängt von den Präferenzen des Teams ab, aber xUnit und NUnit gelten als flexibler für komplexe Szenarien.
Beispiel eines Tests mit xUnit
Betrachten wir das Testen eines einfachen Taschenrechners mit xUnit:
using Xunit;
public class Calculator{ public int Add(int a, int b) => a + b; public int Divide(int a, int b) => b == 0 ? throw new DivideByZeroException() : a / b;}
public class CalculatorTests{ [Fact] public void Add_ShouldReturnSum_WhenTwoNumbers() { // Arrange var calc = new Calculator();
// Act var result = calc.Add(3, 5);
// Assert Assert.Equal(8, result); }
[Theory] [InlineData(10, 2, 5)] [InlineData(9, 3, 3)] [InlineData(7, 1, 7)] public void Divide_ShouldReturnQuotient(int a, int b, int expected) { var calc = new Calculator(); var result = calc.Divide(a, b); Assert.Equal(expected, result); }
[Fact] public void Divide_ShouldThrow_WhenDivideByZero() { var calc = new Calculator(); Assert.Throws<DivideByZeroException>(() => calc.Divide(5, 0)); }}Das Attribut [Fact] kennzeichnet einen normalen Test, während [Theory] mit [InlineData] es ermöglicht, einen Test mit verschiedenen Eingabedaten auszuführen.
Tools für Mock-Objekte
Beim Unit-Testen muss die zu testende Klasse oft von externen Abhängigkeiten (Datenbanken, APIs, Dateisystem) isoliert werden. Dafür werden Mock-Frameworks verwendet:
- Moq — das beliebteste, einfache Syntax, gute Dokumentation.
- NSubstitute — prägnanter, mit einer fluent-Schnittstelle.
- FakeItEasy — eine benutzerfreundliche API zum schnellen Erstellen von Stubs.
Beispiel für die Verwendung von Moq
Angenommen, wir haben einen Dienst, der E-Mails versendet. Wir möchten die Logik testen, ohne tatsächlich zu senden:
using Moq;using Xunit;
public interface IEmailSender{ void Send(string to, string subject, string body);}
public class NotificationService{ private readonly IEmailSender _sender; public NotificationService(IEmailSender sender) => _sender = sender;
public void NotifyUser(string email, string message) { if (string.IsNullOrWhiteSpace(email)) throw new ArgumentException("Email is required"); _sender.Send(email, "Notification", message); }}
public class NotificationServiceTests{ [Fact] public void NotifyUser_ShouldCallSend_WhenValidEmail() { // Arrange var mockSender = new Mock<IEmailSender>(); var service = new NotificationService(mockSender.Object);
// Act service.NotifyUser("test@example.com", "Hello!");
// Assert mockSender.Verify(s => s.Send("test@example.com", "Notification", "Hello!"), Times.Once); }
[ Auch in der Bibliothek
CLI-Frameworks für Go (Golang): Ein vollständiger Überblick über Tools zur Erstellung von Konsolenanwendungen
SMS-Versand per API auf Node.js: Bibliothek twilio
Log4j 2 / SLF4J für Java: Vollständiger Leitfaden mit Beispielen
Jetpack Compose für Kotlin: Vollständiger Leitfaden mit Beispielen
Biometric für Kotlin: Vollständige Anleitung mit Beispielen