Peut-on se moquer de Moq?

Je suis en train de me moquer de certaines dépendances externes et j’ai des problèmes avec une classe tierce qui prend dans son constructeur une instance d’une autre classe tierce. Espérons que la communauté SO pourra me donner des indications.

Je veux créer une instance SomeRelatedLibraryClass de SomeRelatedLibraryClass qui SomeRelatedLibraryClass dans son constructeur une instance SomeLibraryClass de SomeLibraryClass . Comment puis-je me moquer de SomeRelatedLibraryClass cette façon?

Le code de repo …

Voici une méthode Main que j’utilise dans mon application console de test.

 public static void Main() { try { SomeLibraryClass slc = new SomeLibraryClass("direct to 3rd party"); slc.WriteMessage("3rd party message"); Console.WriteLine(); MyClass mc = new MyClass("through myclass"); mc.WriteMessage("myclass message"); Console.WriteLine(); Mock mockMc = new Mock("mock myclass"); mockMc.Setup(i => i.WriteMessage(It.IsAny())) .Callback((ssortingng message) => Console.WriteLine(ssortingng.Concat("Mock SomeLibraryClass WriteMessage: ", message))); mockMc.Object.WriteMessage("mock message"); Console.WriteLine(); } catch (Exception e) { ssortingng error = ssortingng.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToSsortingng()); Console.WriteLine(error); } finally { Console.Write("Press any key to continue..."); Console.ReadKey(); } } 

Voici une classe que j’ai utilisée pour envelopper une classe tierce et lui permettre d’être Moq’d:

 public class MyClass { private SomeLibraryClass _SLC; public MyClass(ssortingng constructMsg) { _SLC = new SomeLibraryClass(constructMsg); } public virtual void WriteMessage(ssortingng message) { _SLC.WriteMessage(message); } } 

Voici deux exemples de classes tierces avec lesquelles je travaille ( VOUS NE POUVEZ PAS LES MODIFIER ):

 public class SomeLibraryClass { public SomeLibraryClass(ssortingng constructMsg) { Console.WriteLine(ssortingng.Concat("SomeLibraryClass Constructor: ", constructMsg)); } public void WriteMessage(ssortingng message) { Console.WriteLine(ssortingng.Concat("SomeLibraryClass WriteMessage: ", message)); } } public class SomeRelatedLibraryClass { public SomeRelatedLibraryClass(SomeLibraryClass slc) { //do nothing } public void WriteMessage(ssortingng message) { Console.WriteLine(ssortingng.Concat("SomeRelatedLibraryClass WriteMessage: ", message)); } } 

Autant que je sache, si la classe que vous essayez de simuler n’est ni virtuelle ni une interface, vous ne pouvez pas vous moquer de lui avec Moq. Si votre bibliothèque tierce partie n’implémente pas ses classes, je pense que vous n’avez pas de chance.

Je suggère d’utiliser le modèle de passerelle . Plutôt que de dépendre directement de SomeRelatedLibraryClass, créez une interface ISomeRelatedLibraryClassGateway. Exposez toutes les méthodes de SomeRelatedLibraryClass que vous devez appeler avec des méthodes de même signature sur ISomeRelatedLibraryClassGateway.

 public interface ISomeRelatedLibraryClassGateway { void WriteMessage(ssortingng message); } 

Créez ensuite une implémentation qui achemine tous les appels vers la classe tierce:

 public class SomeRelatedLibraryClassGateway : ISomeRelatedLibraryClassGateway { private readonly SomeRelatedLibraryClass srlc; public SomeRelatedLibraryClassGateway(SomeRelatedLibraryClass srlc) { this.srlc = srlc; } void ISomeRelatedLibraryClassGateway.WriteMessage(ssortingng message) { srlc.WriteMessage(message); } } 

Désormais, les classes de votre application qui dépendent de SomeRelatedLibraryClass peuvent désormais dépendre de ISomeRelatedLibraryClassGateway et cette interface est facile à simuler. La classe SomeRelatedLibraryClassGateway n’a pas vraiment besoin de tests unitaires; il ne fait que passer des appels. Il doit être testé lors d’un test fonctionnel, mais vous pouvez effectuer des tests fonctionnels sans simulacre.

J’espère que cela t’aides.