Question

Je cherche à me moquer de certaines dépendances externes et je rencontre des problèmes avec une classe tierce qui intègre dans son constructeur une instance d'une autre classe tierce. Espérons que la communauté SO pourra me donner une orientation.

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

Le code du référentiel ...

Voici une méthode Main que j'utilise dans mon application de 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<MyClass> mockMc = new Mock<MyClass>("mock myclass");
        mockMc.Setup(i => i.WriteMessage(It.IsAny<string>()))
            .Callback((string message) => Console.WriteLine(string.Concat("Mock SomeLibraryClass WriteMessage: ", message)));

        mockMc.Object.WriteMessage("mock message");
        Console.WriteLine();
    }
    catch (Exception e)
    {
        string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
        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(string constructMsg)
    {
        _SLC = new SomeLibraryClass(constructMsg);
    }

    public virtual void WriteMessage(string 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(string constructMsg)
    {
        Console.WriteLine(string.Concat("SomeLibraryClass Constructor: ", constructMsg));
    }

    public void WriteMessage(string message)
    {
        Console.WriteLine(string.Concat("SomeLibraryClass WriteMessage: ", message));
    }
}

public class SomeRelatedLibraryClass
{
    public SomeRelatedLibraryClass(SomeLibraryClass slc)
    {
        //do nothing
    }

    public void WriteMessage(string message)
    {
        Console.WriteLine(string.Concat("SomeRelatedLibraryClass WriteMessage: ", message));
    }
}
Était-ce utile?

La solution

Si je comprends bien, 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 n'implémente pas ses classes, je pense que vous n’avez pas de chance.

Autres conseils

Je suggérerais d'utiliser le modèle Gateway . 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 la même signature sur ISomeRelatedLibraryClassGateway.

public interface ISomeRelatedLibraryClassGateway {
  void WriteMessage(string 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(string message) {
    srlc.WriteMessage(message);
  }
}

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

J'espère que cela vous aidera.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top