89 votes

Méthodes statiques d'asservissement

Récemment, j'ai commencé à utiliser Moq pour le test unitaire. J'utilise Moq pour simuler les classes que je n'ai pas besoin de tester.

Comment traitez-vous généralement les méthodes statiques ?

public void foo(string filePath)
{
    File f = StaticClass.GetFile(filePath);
}

Comment cette méthode statique pourrait-elle, StaticClass.GetFile() se faire moquer ?

P.S. J'apprécierais toute lecture que vous recommandez sur Moq et les tests unitaires.

56voto

Jeco Points 540

@Pure.Krome : bonne réponse mais je vais ajouter quelques détails

@Kevin : Il faut choisir une solution en fonction des modifications que l'on peut apporter au code.
Si vous pouvez le changer, certaines injections de dépendances rendent le code plus testable. Si vous ne pouvez pas, vous avez besoin d'une bonne isolation.
Avec les frameworks de mocking gratuits (Moq, RhinoMocks, NMock...) vous ne pouvez mocker que les délégués, les interfaces et les méthodes virtuelles. Donc, pour les méthodes statiques, scellées et non virtuelles vous avez 3 solutions :

  • Isolateur TypeMock (on peut se moquer de tout mais c'est cher)
  • JustMock de Telerik (nouveau venu, moins cher mais pas encore gratuit)
  • Taupes de Microsoft (la seule solution gratuite pour l'isolation)

Je recommande les taupes parce qu'il est gratuit, efficace et utilise des expressions lambda comme Moq. Juste un détail important : Moles fournit des stubs, pas des mocks. Vous pouvez donc toujours utiliser Moq pour les interfaces et les délégués ;)

Mock : une classe qui implémente une interface et permet de définir dynamiquement les valeurs à renvoyer/les exceptions à lancer à partir de méthodes particulières et offre la possibilité de vérifier si des méthodes particulières ont été appelées/non appelées.
Stub : Comme une classe fantaisie, sauf qu'elle ne permet pas de vérifier que les méthodes ont été appelées ou non.

11 votes

Comme une mise à jour de ceci. Moles est maintenant appelé Fakes et est intégré dans Visual Studio 2012 : msdn.microsoft.com/fr/us/library/hh549175.aspx

2 votes

Dans Moles, vous pouvez vérifier si une méthode a été appelée en ajoutant simplement une variable booléenne et en la mettant à true à l'intérieur du stub de la fonction. Vous pouvez également vérifier tous les paramètres de l'appel avec ce workarround.

3 votes

Votre définition des mocks et des stubs est plus compliquée que nécessaire. Un mock est un faux objet avec lequel vous affirmez qu'un certain comportement s'est produit. Un stub est un faux objet qui n'est utilisé que pour fournir des données "en boîte" au test. Les stubs ne font jamais l'objet d'une assertion. En bref, les mocks concernent le comportement et les stubs l'état.

37voto

Pure.Krome Points 28473

Les cadres de simulation comme Moq ou Rhinomocks ne peuvent créer que des instances de simulation d'objets, ce qui signifie que la simulation de méthodes statiques n'est pas possible.

Vous pouvez également recherche Google pour plus d'informations.

Il y a aussi quelques questions posées précédemment sur StackOverflow. aquí , aquí y aquí .

21voto

pt12lol Points 341

Il est possible dans .NET d'exclure MOQ et toute autre bibliothèque de simulateurs. Vous devez faire un clic droit dans l'explorateur de solutions sur l'assemblage contenant la méthode statique que vous voulez simuler et choisir Ajouter l'assemblage de faux . Ensuite, vous pouvez librement simuler les méthodes statiques de l'assemblée.

Supposons que vous voulez vous moquer System.DateTime.Now méthode statique. Faites-le par exemple de cette façon :

using (ShimsContext.Create())
{
    System.Fakes.ShimDateTime.NowGet = () => new DateTime(1837, 1, 1);
    Assert.AreEqual(DateTime.Now.Year, 1837);
}

Vous avez une propriété similaire pour chaque propriété statique et méthode.

15 votes

Un avertissement aux personnes qui trouvent ce : MS Fakes est intégré dans Visual Studio 2012+ Premium/Ultimate uniquement. Vous ne pourrez probablement pas l'intégrer dans une chaîne d'intégration continue.

3 votes

Cela devrait être la réponse acceptée. MS Fakes avec les cales rend maintenant très possible de se moquer des méthodes statiques.

2 votes

Soyez TRÈS prudent en utilisant les faux MS ! Fakes est un framework de redirection, et son utilisation conduit rapidement à une mauvaise architecture. N'utilisez Fakes qu'en cas de nécessité absolue, pour intercepter les appels vers des bibliothèques tierces ou (très) anciennes. La meilleure solution est de créer un wrapper de classe avec une interface, puis de passer l'interface par injection de constructeur ou via un framework d'injection. Mockez l'interface, puis passez-la dans le code à tester. Restez à l'écart des faux, dans la mesure du possible.

11voto

mr100 Points 3559

Vous pouvez y parvenir avec Pose disponible sur nuget. Elle vous permet de simuler, entre autres, les méthodes statiques. Dans votre méthode de test, écrivez ceci :

Shim shim = Shim.Replace(() => StaticClass.GetFile(Is.A<string>()))
    .With((string name) => /*Here return your mocked value for test*/);
var sut = new Service();
PoseContext.Isolate(() =>
    result = sut.foo("filename") /*Here the foo will take your mocked implementation of GetFile*/, shim);

Pour plus d'informations, voir ici https://medium.com/@tonerdo/unit-testing-datetime-now-in-c-without-using-interfaces-978d372478e8

3voto

sirdank Points 1021

J'ai aimé Pose, mais je n'ai pas réussi à l'empêcher de lancer InvalidProgramException, qui semble être un problème connu. numéro . Maintenant, j'utilise Smocks comme ça :

Smock.Run(context =>
{
    context.Setup(() => DateTime.Now).Returns(new DateTime(2000, 1, 1));

    // Outputs "2000"
    Console.WriteLine(DateTime.Now.Year);
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X