J'utilise mocha afin de tester unitaire une application écrite pour node.js
Je me demande s'il est possible de tester des fonctions unitaires qui n'ont pas été exportées dans un module.
Exemple:
J'ai beaucoup de fonctions définies comme ça dans foobar.js
function private_foobar1(){
...
}
function private_foobar2(){
...
}
et quelques fonctions exportées en public:
exports.public_foobar3 = function(){
...
}
Le scénario de test est structuré comme suit:
describe("private_foobar1", function() {
it("should do stuff", function(done) {
var stuff = foobar.private_foobar1(filter);
should(stuff).be.ok;
should(stuff).....
Évidemment, cela ne fonctionne pas, car il private_foobar1
n'est pas exporté.
Quelle est la bonne façon de tester les méthodes privées unitaire? Mocha a-t-il des méthodes intégrées pour faire cela?
Réponses:
Si la fonction n'est pas exportée par le module, elle ne peut pas être appelée par code de test en dehors du module. Cela est dû au fonctionnement de JavaScript, et Mocha ne peut pas à lui seul contourner cela.
Dans les quelques cas où j'ai déterminé que tester une fonction privée était la bonne chose à faire, j'ai défini une variable d'environnement que mon module vérifie pour déterminer si elle s'exécute dans une configuration de test ou non. S'il s'exécute dans la configuration de test, il exporte des fonctions supplémentaires que je peux ensuite appeler pendant le test.
Le mot «environnement» est utilisé ici de manière vague. Cela peut signifier une vérification
process.env
ou autre chose qui peut communiquer au module "vous êtes testé maintenant". Les instances où j'ai dû faire cela se trouvaient dans un environnement RequireJS, et j'ai utilisémodule.config
à cette fin.la source
SyntaxError: 'import' and 'export' may only appear at the top level
import
, à l'export
intérieur d'un bloc. Finalement, vous serez en mesure d'accomplir ce genre de chose dans ES6 avec le chargeur système. Une façon de le contourner maintenant consiste à utilisermodule.exports = process.env.NODE_ENV === 'production' ? require('prod.js') : require('dev.js')
et à stocker vos différences de code es6 dans ces fichiers respectifs.Découvrez le module de recâblage . Il vous permet d'obtenir (et de manipuler) des variables et des fonctions privées dans un module.
Donc, dans votre cas, l'utilisation serait quelque chose comme:
la source
Cannot find module '../../package' from 'node.js'
. Quelqu'un connaît-il cela?.ts
,typescript
je cours en utilisantts-node
@cluVoici un très bon workflow pour tester vos méthodes privées expliqué par Philip Walton, un ingénieur Google sur son blog.
Principe
_
par exempleEnsuite, utilisez une tâche de construction ou votre propre système de construction (par exemple grunt-strip-code) pour supprimer ce bloc pour les versions de production.
Vos versions de test ont accès à votre API privée, contrairement à vos versions de production.
Fragment
Écrivez votre code comme ceci:
Et tes tâches grognantes comme ça
Plus profond
Dans un article ultérieur , il explique le «pourquoi» du «test de méthodes privées»
la source
Si vous préférez garder les choses simples, exportez simplement les membres privés également, mais clairement séparés de l'API publique avec une convention, par exemple les préfixer avec un
_
ou les imbriquer sous un seul objet privé .la source
J'ai créé un package npm à cet effet que vous pourriez trouver utile: require-from
Fondamentalement, vous exposez des méthodes non publiques en:
Remarque:
testExports
peut être n'importe quel nom valide que vous voulez, saufexports
bien sûr.Et depuis un autre module:
la source
requireFrom
avec les bons paramètres.) Aussi, si le module avectextExports
est chargé par unrequire
appel avant de lerequireFrom
charger,requireFrom
il retourneraundefined
. (Je viens de le tester.) Bien qu'il soit souvent possible de contrôler l'ordre de chargement des modules, ce n'est pas toujours pratique. (Comme en témoignent certaines questions de Mocha sur SO.) Cette solution ne fonctionnera généralement pas non plus avec les modules de type AMD. (Je charge des modules AMD dans Node quotidiennement pour les tests.)J'ai ajouté une fonction supplémentaire que je nomme Internal () et renvoie toutes les fonctions privées à partir de là. Cette fonction interne () est ensuite exportée. Exemple:
Vous pouvez appeler les fonctions internes comme ceci:
J'aime mieux cette solution parce que:
la source
J'ai suivi la réponse de @barwin et vérifié comment les tests unitaires peuvent être effectués avec rewire module . Je peux confirmer que cette solution fonctionne simplement.
Le module devrait être exigé en deux parties - une publique et une privée. Pour les fonctions publiques, vous pouvez le faire de manière standard:
Pour une portée privée:
Afin d'en savoir plus sur le sujet, j'ai créé un exemple de travail avec des tests de modules complets, les tests incluent une portée privée et publique.
Pour plus d'informations, je vous encourage à consulter l'article ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ) décrivant complètement le sujet, il comprend des exemples de code.
la source
Je sais que ce n'est pas nécessairement la réponse que vous recherchez, mais ce que j'ai trouvé, c'est que la plupart du temps, si une fonction privée vaut la peine d'être testée, elle vaut la peine d'être dans son propre fichier.
Par exemple, au lieu d'avoir des méthodes privées dans le même fichier que les méthodes publiques, comme ceci ...
src / chose / PublicInterface.js
... vous le divisez comme ceci:
src / chose / PublicInterface.js
src / chose / interne / helper1.js
src / chose / interne / helper2.js
De cette façon, vous pouvez facilement tester
helper1
ethelper2
tel quel, sans utiliser Rewire et d'autres "magies" (qui, j'ai trouvé, ont leurs propres points faibles lors du débogage, ou lorsque vous essayez de vous déplacer vers TypeScript, pour ne pas mentionner plus pauvre compréhensibilité pour les nouveaux collègues). Et le fait de les placer dans un sous-dossier appeléinternal
, ou quelque chose du genre, aidera à éviter leur utilisation accidentelle dans des endroits non souhaités.PS: Une autre question commune avec des méthodes « privées » est que si vous voulez tester
publicMethod1
etpublicMethod2
et se moquer des aides, encore une fois, vous avez normalement besoin de quelque chose comme ReWire de le faire. Cependant, s'ils sont dans des fichiers séparés, vous pouvez utiliser Proxyquire pour le faire, qui, contrairement à Rewire, ne nécessite aucune modification de votre processus de construction, est facile à lire et à déboguer, et fonctionne bien même avec TypeScript.la source
Pour rendre les méthodes privées disponibles pour les tests, je fais ceci:
la source