web-dev-qa-db-fra.com

Comment tester les fonctions non exportées de façon unitaire?

Dans un module Javascript es6, il peut y avoir de nombreuses petites fonctions faciles à tester qui devraient être testées, mais ne devraient pas être exportées. Comment tester les fonctions d'un module sans les exporter? (sans utiliser recâbler )

10
Jordan

Exporter une const "testables"

function shouldntBeExportedFn(){
  // Does stuff that needs to be tested
  // but is not for use outside of this package
}
export function exportedFn(){
  // A function that should be called
  // from code outside of this package and
  // uses other functions in this package
  return shouldntBeExportedFn();
}
export const testables = {
  shouldntBeExportedFn:shouldntBeExportedFn
}

Maintenant

import {exportedFn} from './myPackage';

peut être utilisé dans le code de production et

import {exportedFn, testables} from './myPackage';
const {shouldntBeExportedFn} = testables;

peut être utilisé dans les tests unitaires.

De cette façon, il conserve les indices de contexte pour les autres développeurs de mon équipe que shouldntBeExportedFn() ne doit pas être utilisé en dehors du package, sauf pour les tests.

Edit: J'utilise ce modèle depuis près d'un an maintenant, et je trouve que cela fonctionne très bien.

10
Jordan

J'aimerais avoir une meilleure réponse pour toi Jordan. ???? J'ai eu une question très similaire dans les contextes JS et C # dans le passé ...

Anwser, not answer

À un moment donné, j'ai dû accepter le fait que si je veux des tests unitaires granulaires couvrant des fonctions/méthodes non exportées/privées, je devrais vraiment les exposer. Certaines personnes diraient que c'est une violation de l'encapsulation, mais d'autres ne sont pas d'accord avec cela. L'ancien groupe de personnes dirait également que tant qu'une fonction n'est pas exportée/publique, c'est essentiellement un détail d'implémentation, donc ne devrait pas être testé à l'unité.

Si vous pratiquez le TDD alors l'explication de Mark Seeman devrait être pertinente (PluralSight) et j'espère que cela clarifiera pourquoi il est normal d'exposer les choses.

Je ne sais pas si vous pouvez trouver une astuce pour invoquer les fonctions non exportées directement à partir de vos tests unitaires sans apporter de modifications au code testé, mais je n'irais pas dans ce sens personnellement.

Juste une option

Une autre option consiste à diviser votre bibliothèque en deux. Par exemple, la bibliothèque A est le code de votre application et la bibliothèque B est le package qui contient toutes les fonctions que vous souhaitez éviter d'exporter depuis l'interface de A.

S'il s'agit de deux bibliothèques différentes, vous pouvez contrôler à un niveau très fin ce qui est exposé et comment il est testé. La bibliothèque A dépendra simplement de B sans divulguer aucun des détails de B. A et B sont alors testables indépendamment.

Cela nécessitera une organisation de code différente, bien sûr, mais cela fonctionnera. Des outils comme Lerna simplifient les référentiels multi-packages pour le code JavaScript.

Note latérale

Pour être honnête, je ne suis pas d'accord avec @ AlexSzabó. Tester la fonction non exportée en testant la ou les fonctions qui l'utilisent n'est pas vraiment un test unitaire.

4
Igor Soloydenko