Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C#] Tests unitaires bouchonner un appel d'une mét

utilisation de MOQ

Sujet résolu
    25 juin 2019 à 11:53:09

    Bonjour,

    Je vous sollicite car je me casse les dents depuis plusieurs jours sur des tests unitaires.

    J'ai une class de traitement avec ses méthodes et une autre class de service qui me permet de faire le lien et récupérer des données de ma BDD.

    Je souhaite tester une méthode de ma class de "traitement" et bouchonner/simuler/intercepter l'appel vers ma BDD.

    Pour exemple :

    public class Client
        {
            public int id { get; set; }
            public int nom { get; set; }
        }
    
    public interface ITraitement
        {
            Client GetProfilClient(int id);
        }
    
    
    public class Traitement_singleton : ITraitement
        {
            // ...... code pour singleton
    
            public Client GetProfilClient(int id)
            {
                // ..... code
    
                Client client = ClientServices.Instance.GetDataClient(id); //singleton
    
                // ..... code
    
                return client;
            }
        }
    
    public interface IClientServices
        {
            Client GetDataClient(int id);
        }
    
    public class ClientServices_Singleton : IClientServices
        {
            // ...... code pour singleton
    
            public Client GetDataClient(int id)
            {
                Client c = new Client()
    
                /*
                 * Requete SQL vers ma BDD et tout et tout
                 * Récupération des données sur mon client 
                 */
    
                return c;
            }
        }

    Mon but est d'intercepter l'appel "ClientServices.GetDataClient(id)" dans la méthode "GetProfilClient" de la class "Traitement_singleton"

    Pour me détacher de toutes dépendance externe.

    J'ai vu pas mal de chose de internet, même sur open class room mais je dois passer à coté d'un truc, et je ne sais pas quoi !

    Merci d'avance pour les réponse.

    [Ajout]

    Voici un test qui passe mais qui ne répond pas à mon problème :(

    public void TestMethod1()
    {
    	// Création du client attendu en sortie pour les Assert
    	Client clientEntree = new Client(){
    		id = 1,
    		nom = dupont
    	}
    
    	//Déclaration de mon mock
    	ITraitement TraitementMock = Mock.Of<ITraitement>();
    
    	//Gestion du comportement
        Mock.Get(TraitementMock).Setup(dal => dal.GetProfilClient(It.IsAny<int>())).Returns(client).Callback(() => Console.WriteLine("Interception"));
    
        // Appel
    	Client clientSortie = TraitementMock.GetProfilClient(999); // Client 999 n'existe pas, retourne la valeur null
    
    	// Vérification
    	Assert.IsNotNull(clientSortie);
    }



    -
    Edité par FinalSo 25 juin 2019 à 12:06:16

    • Partager sur Facebook
    • Partager sur Twitter
      25 juin 2019 à 12:29:53

      Salut,

      Je ne vois pas trop où est le soucis, tu as l'air d'avoir compris ce qu'il te fallait.

      Pour moi il te faut juste une autre classe implémentant IClientServices. Dans ta méthode GetDataClient, au lieu d'aller faire ta requête en BDD, tu peux tout à fait créer ton objet "en dur" pour te libérer de cette dépendance.

      Ainsi tu as juste à changer l'instanciation de ton IClientServices, c'est à dire remplacer ClientServices_Singleton par ClientServices_Mock (par exemple)

      public class ClientServices_Mock : IClientServices
      {
          public Client GetDataClient(id)
          {
              Client c = new Client().
              c.id=id;
              c.nom="unNom";
              return c;
          }
      }

      Cela répond il a ta question ?

      • Partager sur Facebook
      • Partager sur Twitter
        25 juin 2019 à 13:03:25

        Merci pour la réponse rapide,

        tu réponds en partie, mais je vois les choses différemment (je me trompe surement car j'arrive pas à mes fins).

        En fait je pensais faire une interception un peu comme ça :

        //Déclaration de mon mock ClientService
        IClientServices ClientServiceMock = Mock.Of<IClientServices>();
        
        // Configuration de l'interception
        Mock.Get(ClisntServiceMock).Setup(dal => dal.GetDataClient(It.IsAny<int>())).Returns(client).Callback(() => Console.WriteLine("Interception"));

        Où je ferai la configuration directement dans mon test Unitaire en lui disant :

        Si tu rencontres l'appel de cette méthode ("GetDataClient()") contenu dans cette interface ("ClientServiceMock") --> interception.

        Du coup j'aurai pas de nouvelle classe parallèle à créer (comme pour ta solution).

        Possible?

        ta solution est une bonne piste.



        -
        Edité par FinalSo 25 juin 2019 à 13:05:25

        • Partager sur Facebook
        • Partager sur Twitter
          25 juin 2019 à 13:20:24

          Ah, en fait je t'ai proposé la manière "fait maison" un peu dégueulasse, donc bonne piste, pas tant que ca.

          Dans cet article, ils te proposent la manière propre, qui reprend un peu ce que tu as montré dans ton post, mais tu as sans doute du tomber dessus.

          https://cmatskas.com/improve-your-unit-tests-with-mock-of/

          J'ai répondu trop vite, mon mauvais !

          -
          Edité par earp91 25 juin 2019 à 13:21:54

          • Partager sur Facebook
          • Partager sur Twitter
            27 juin 2019 à 15:06:57

            Merci pour l'aide,

            Mais ça a l'air d'être une grosse galère pour mon projet actuel de mettre ces tests en place.

            Car j'ai des class qui sont en singleton et des class static.

            Or il faut refaire le code de ces class pour faire de l'injection d'interface afin de réaliser les types de tests que je souhaite faire.

            Du coup, ça m'a un peu démoralisé car impossible de refaire le code déjà existant.

            J'envisagerai de le faire sur un nouveau projet.

            Merci

            • Partager sur Facebook
            • Partager sur Twitter
              27 juin 2019 à 16:35:01

              C'est sur que pour l'injection, vaut mieux le savoir au début du projet !

              Bon courage

              • Partager sur Facebook
              • Partager sur Twitter

              [C#] Tests unitaires bouchonner un appel d'une mét

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown