Tests en C# (.NET) : aperçu des frameworks et outils
Des tests de qualité sont la base d'un logiciel fiable sur la plateforme .NET. Dans l'écosystème C#, il existe plusieurs frameworks matures pour les tests unitaires, d'intégration et d'acceptation. Dans cet article, nous allons passer en revue les principaux outils, leurs caractéristiques et fournir des exemples pratiques de code.
Principaux frameworks pour les tests unitaires
Dans .NET Core et .NET 5+, la prise en charge intégrée des tests est implémentée via trois frameworks principaux :
- MSTest — le framework classique de Microsoft, simple pour les débutants.
- NUnit — un framework open-source populaire avec un riche ensemble d'attributs.
- xUnit.net — un outil moderne, léger et flexible, créé par l'auteur de NUnit.
Tous les trois sont pris en charge dans Visual Studio, Rider et via dotnet CLI. Le choix dépend des préférences de l'équipe, mais xUnit et NUnit sont considérés comme plus flexibles pour les scénarios complexes.
Exemple de test avec xUnit
Examinons le test d'une calculatrice simple avec 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)); }}L'attribut [Fact] désigne un test standard, tandis que [Theory] avec [InlineData] permet d'exécuter un même test avec différentes données d'entrée.
Outils pour les objets mock
Lors des tests unitaires, il est souvent nécessaire d'isoler la classe testée des dépendances externes (base de données, API, système de fichiers). Pour cela, on utilise des frameworks de mock :
- Moq — le plus populaire, syntaxe simple, bonne documentation.
- NSubstitute — plus concis, avec une interface fluide.
- FakeItEasy — API conviviale pour créer rapidement des bouchons.
Exemple d'utilisation de Moq
Supposons que nous ayons un service qui envoie des emails. Nous voulons tester la logique sans envoi réel :
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); }
[ Aussi dans la bibliothèque
Création d'outils CLI sur Node.js : aperçu des frameworks Commander, Yargs et Inquirer
ts-jest pour TypeScript : guide complet avec exemples
NestJS pour TypeScript : guide complet avec exemples