Une des bonnes pratiques d’un projet informatique est la mise en place de tests unitaires. Je vais vous présentez 2 librairies, disponible sous forme de package NuGet, pour vous aidez dans l’écriture de tests.
Moq
Le but d’un test unitaire est de tester un composant isolé, d’où la nécessité d’utiliser une librairie permettant de faire du Mock. J’utilise pour cela Moq.
Les exemples de tests suivant utilisent NUnit comme framework de tests unitaires. Afin de pouvoir facilement remplacer les dépendances des classes à tester, j’utilise Unity comme container d’injection de dépendance (IoC). Vous allez ainsi pouvoir facilement passer à votre classe dans le constructeur votre Mock.
Voyons comment configurer et effectuez des assertions sur vos mock avec Moq :
using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using NFluent; using NUnit.Framework; namespace Demo.Tests { [TestFixture] public class MyServiceTests : BaseServicesTests { private Mock<IMyService> myServiceMock; private Mock<ILogger> loggerMock; private IMyClass myClass; [SetUp] public override void SetUp() { base.SetUp(); //Create Mocks myServiceMock = new Mock<IMyService>(); loggerMock = new Mock<ILogger>(); //We pass our mock to the instance to test myClass = new MyClass(myServiceMock, loggerMock); } [Test] public void MyMethodShouldReturnTrue() { //Setup method on service to return expected value to test our case //Here we setup to return an empty list of string myServiceMock.Setup(m => m.GetData()).Returns(new List<string>()); var result = myClass.MyMethod(); //Verify the result is what is expected Check.That(result).IsTrue(); //Verify that our mock has been called myServiceMockSetup.Verify(m => m.GetData(), Times.Once); } } }
Moq fournit un ensemble de méthodes permettant de configurer (Setup + Returns/Callbacks) et d’effectuer des tests sur les mocks (Verify).
On peut par exemple vérifier le nombre d’appel d’une méthode, les paramètres, …
Voici comment vérifier qu’un méthode prenant un paramètre de type string a bien été appelé 2 fois avec comme valeur de paramètre « MyTestString »
myServiceMock.Verify(r => r.MyMethod(It.Is<string>(x => x == "MyTestString")), Times.Exactly(2));
NFluent
Comme vous avez pu peut être le remarquer, je fais pas mal de JavaScript en ce moment et j’aime beaucoup les librairies de tests style jasmine, should, … qui permettent de décrire les assertions de manière plus lisibles. En .Net, j’utilise NFluent qui permet d’avoir une API d’assertion fluent où l’on peut chaîner les assertions à la suite les une des autres.
Check.That(julien) .IsNotNull() .And.IsNotEqualTo(david) .And.IsInstanceOf<Person>();
Dans l’exemple ci-dessus, je vérifie que le l’objet julien n’est pas null, n’est pas égal à david et que cet objet est une instance de la classe Person.
D’autres exemples d’assertions :
//Collections //Nombre d'élément d'une collection Check.That(persons).HasSize(3); //Il existe une personne ayant la propriété Name égale à Julien Check.That(persons.Extracting("Name")).Contains("Julien"); //Test des exceptions Check.ThatCode(() => myService.MyMethod()) .Throws<MyException>() .WithMessage("MyMessage") .And.WithProperty("MessageKey", "MyMessageKey");
Voici des exemples d’assertion avec NFluent.
Liens
- Des alternatives à Moq (non testés)
- Des alternatives à NFluent (non testés)
- FluentAssertions
- NUnit Constraint Model : l’API Fluent de NUnit qu’on utilise avec Assert (pas trop fan de cette approche)
- un article présentant NFluent
- Une Vidéo sur Channel 9 concernant l’injection de dépendance et les tests en .Net
- Un article sur le TDD en 6 parties en .Net
Bon tests 🙂 …
Tweet