Question

Je suis nouveau dans le domaine des objets fictifs, mais je comprends que mes classes doivent implémenter des interfaces pour pouvoir les imiter.

Le problème que je rencontre est que, dans ma couche d'accès aux données, je souhaite utiliser des méthodes statiques, mais je ne peux pas en insérer dans une interface.

Quel est le meilleur moyen de contourner cela? Devrais-je simplement utiliser des méthodes d'instance (ce qui semble faux) ou existe-t-il une autre solution?

Était-ce utile?

La solution

Je voudrais utiliser un modèle d'objet de méthode. Ayez une instance statique de cela et appelez-la dans la méthode statique. Il devrait être possible de sous-classer pour les tests, en fonction de votre environnement moqueur.

i.e. dans votre classe avec la méthode statique ont:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

et votre objet de méthode peuvent être très simples et faciles à tester:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}

Autres conseils

Oui, vous utilisez des méthodes d'instance. Les méthodes statiques disent en gros: "Il existe un moyen d’accomplir cette fonctionnalité: elle n’est pas polymorphe". Le moquage repose sur le polymorphisme.

Maintenant, si vos méthodes statiques ne se soucient pas logiquement de l'implémentation que vous utilisez, elles pourraient peut-être prendre les interfaces en tant que paramètres, ou peut-être travailler sans aucune interaction avec state - mais sinon, vous devriez utiliser des instances (et probablement une injection de dépendance pour tout relier entre eux).

J'ai trouvé un blog via Google avec quelques excellents exemples sur la façon de procéder:

  1. La classe Refactor doit être une classe d'instance et implémenter une interface.

    Vous avez déjà indiqué que vous ne souhaitiez pas faire cela.

  2. Utiliser une classe d'instance wrapper avec des délégués pour les membres de classes statiques

    Ce faisant, vous pouvez simuler une interface statique via des délégués.

  3. Utilisez une classe d'instance wrapper avec des membres protégés qui appellent la classe statique

    C’est probablement le plus facile à simuler / gérer sans refactoring car il peut simplement être hérité et étendu.

Vous essayez peut-être de tester à un point de départ trop profond. Il n'est pas nécessaire de créer un test pour tester chaque méthode individuellement. Les méthodes privées et statiques doivent être testées en appelant les méthodes publiques qui appellent ensuite les méthodes privées et statiques.

Disons donc que votre code est comme ceci:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

Vous n'avez pas besoin d'écrire un test sur la méthode TransformData (et vous ne pouvez pas). A la place, écrivez un test pour la méthode GetData qui teste le travail effectué dans TransformData.

Utilisez des méthodes d'instance si possible.

Utilisez des Func [T, U] publics statiques (références de fonctions statiques pouvant être substituées aux fonctions fictives) lorsque les méthodes d'instance ne sont pas possibles.

Une solution simple est de permettre de changer l'implémentation de la classe statique via un setter:

class ClassWithStatics {

  private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();

  // Should only be invoked for testing purposes
  public static void overrideImplementation(IClassWithStaticsImpl implementation) {
     ClassWithStatics.implementation = implementation;
  }

  public static Foo someMethod() {
    return implementation.someMethod();
  }

}

Ainsi, lors de la configuration de vos tests, vous appelez overrideImplementation avec une interface simulée. L'avantage est que vous n'avez pas besoin de changer les clients de votre classe statique. L'inconvénient est que vous aurez probablement un peu de code dupliqué, car vous devrez répéter les méthodes de la classe statique et son implémentation. Mais parfois, les méthodes statiques peuvent utiliser une interface plus étroite qui fournit une fonctionnalité de base.

Le problème que vous rencontrez est lorsque vous utilisez du code tiers et qu'il est appelé à partir de l'une de vos méthodes. Ce que nous avons fini par faire, c’est de l’envelopper dans un objet et de l’appeler avec dep inj, puis votre test d’unité peut simuler une méthode statique tierce et appeler le créateur avec lui.

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