2017-09-27 1 views
0

Existe-t-il un bon outil sous C# pour simuler des interfaces complexes (service, référentiel et autres) avec des implémentations de test partielles?Meilleure interface simulacre/faux avec implémentation partielle

Le cadre fictif que j'utilise actuellement (RhinoMocks) est trop lent et trop difficile à manipuler à cette fin.

Pré-requis:

  • Aucune pénalité de performance significative, par rapport aux implémentations réelles (tests en vrac)
  • de mise en œuvre avec la logique rudimentaire et des données (par exemple: le dictionnaire à la place de la table de base de données)
  • Pas besoin de changer les tests, lorsque l'interface change.

exemple de mise en œuvre complète:

public interface IMyInterface 
{ 
    int PropertyA { get; set; } 
    int PropertyB { get; set; } 
    void DoSomethingWithX(int x); 
    int GetValueOfY(); 
} 

public class FakeImplementation : IMyInterface 
{ 
    private int _valueOfYCalls = 0; 

    public int PropertyA { get; set; } 
    public int PropertyB { get; set; } 
    public void DoSomethingWithX(int x) 
    { } 

    public int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

Le compteur est juste pour simuler la logique rudimentaire.

Le problème est que si l'interface obtient une nouvelle méthode, comme SetSomeZ (int z), le test ne sera plus généré/exécuté, sans changement explicite.

Existe-t-il un framework fake/fock, fonctionnant avec des implémentations de base, mais ajoutant des membres automatiquement, via virtual/override, ou wrapper?

Tels que ceci:

[ImplementsInterface(nameof(IMyInterface))] 
public class FakeImplementationBase 
{ 
    private int _valueOfYCalls = 0; 

    [ImplementsMember(nameof(IMyInterface.GetValueOfY))] 
    public virtual int GetValueOfY() 
    { 
     return _valueOfYCalls++; 
    } 
} 

L'outil/cadre devrait générer des types complets de mise en œuvre à l'exécution, similaire à se moque/talons, mais en utilisant la mise en œuvre de base, tout en ajoutant les éléments d'interface manquants.

Ceci n'est pas supposé être pour des tests unitaires réels, mais pour des objectifs plus complexes. C'est aussi un logiciel hérité avec des interfaces et des classes énormes, pas beaucoup sur la «responsabilité unique».

Répondre

0

Moq est exactement ce que vous voulez.

public interface IFoo { 
    int MethodA(int a); 
    void MethodB(long b); 
    void MethodC(string c); 
    ... 
} 

var MoqFoo = new Mock<IFoo>(); 
MoqFoo.Setup(m => m.MethodA(It.Is(a => a > 0)).Returns<int>(a => a + 1); 
MoqFoo.Setup(m => m.MethodC(It.IsAny<string>()).Callback<string>(c => Debug.Write(c)); 

Notez comment nous n'avons pas fait .Setup() pour la méthode B? Lorsque vous le déclarez, toutes les méthodes et propriétés obtiennent des méthodes/propriétés factices. .Setup() spécifiera vos propres méthodes personnalisées. Par conséquent, si votre interface possède 10 méthodes mais que vous voulez uniquement tester MethodD(), il vous suffit d'écrire du code pour cela.

http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/

+0

Merci, quelles sont les performances comme avec Moq? RhinoMocks a une syntaxe similaire, mais est beaucoup plus lente que les vraies classes (tant qu'elles sont en mémoire uniquement). Je voudrais éviter la syntaxe plutôt complexe de '.Setup (...)' ou '.Stub()' dans RhinoMocks. Je m'attends à ce que le framework crée un nouveau type au moment de l'exécution, qui est instancié comme une classe normale, ne faisant une réflexion qu'une seule fois et ayant ensuite des performances comme une classe codée. –