Ich verwende Mokka, um eine für node.js geschriebene Anwendung zu testen
Ich frage mich, ob es möglich ist, Unit-Test-Funktionen durchzuführen, die nicht in ein Modul exportiert wurden.
Beispiel:
Ich habe viele Funktionen wie diese in definiert foobar.js
function private_foobar1(){
...
}
function private_foobar2(){
...
}
und einige Funktionen, die als öffentlich exportiert wurden:
exports.public_foobar3 = function(){
...
}
Der Testfall ist wie folgt aufgebaut:
describe("private_foobar1", function() {
it("should do stuff", function(done) {
var stuff = foobar.private_foobar1(filter);
should(stuff).be.ok;
should(stuff).....
Offensichtlich funktioniert dies nicht, da private_foobar1
es nicht exportiert wird.
Was ist der richtige Weg, um private Methoden zu testen? Hat Mokka einige eingebaute Methoden, um das zu tun?
Antworten:
Wenn die Funktion nicht vom Modul exportiert wird, kann sie nicht durch Testcode außerhalb des Moduls aufgerufen werden. Das liegt daran, wie JavaScript funktioniert, und Mocha kann dies nicht alleine umgehen.
In den wenigen Fällen, in denen ich festgestellt habe, dass das Testen einer privaten Funktion das Richtige ist, habe ich eine Umgebungsvariable festgelegt, die mein Modul überprüft, um festzustellen, ob sie in einem Test-Setup ausgeführt wird oder nicht. Wenn es im Test-Setup ausgeführt wird, exportiert es zusätzliche Funktionen, die ich dann während des Tests aufrufen kann.
Das Wort "Umwelt" wird hier lose verwendet. Dies kann bedeuten,
process.env
dass das Modul "Sie werden gerade getestet" überprüft wird oder etwas anderes. Die Fälle, in denen ich dies tun musste, waren in einer RequireJS-Umgebung und ich habe siemodule.config
für diesen Zweck verwendet.quelle
SyntaxError: 'import' and 'export' may only appear at the top level
import
,export
innerhalb eines Blocks. Schließlich können Sie dies in ES6 mit dem Systemloader erreichen. Eine Möglichkeit, dies jetzt zumodule.exports = process.env.NODE_ENV === 'production' ? require('prod.js') : require('dev.js')
umgehen, besteht darin , Ihre es6-Codeunterschiede in den jeweiligen Dateien zu verwenden und zu speichern.Überprüfen Sie die Neuverdrahtung . Sie können damit private Variablen und Funktionen innerhalb eines Moduls abrufen (und bearbeiten).
In Ihrem Fall wäre die Verwendung also ungefähr so:
quelle
Cannot find module '../../package' from 'node.js'
. Kennt jemand das?.ts
,typescript
ich laufe mitts-node
@cluHier ist ein wirklich guter Workflow zum Testen Ihrer privaten Methoden , der von Philip Walton, einem Google-Ingenieur in seinem Blog, erklärt wurde.
Prinzip
_
beispielsweise mit einemVerwenden Sie dann eine Build-Task oder Ihr eigenes Build-System (z. B. Grunt-Strip-Code), um diesen Block für Produktions-Builds zu entfernen.
Ihre Test-Builds haben Zugriff auf Ihre private API und Ihre Produktions-Builds nicht.
Snippet
Schreiben Sie Ihren Code wie folgt:
Und deine Grunzaufgaben so
Tiefer
In einem späteren Artikel wird das "Warum" des "Testens privater Methoden" erläutert.
quelle
Wenn Sie es lieber einfach halten möchten, exportieren Sie einfach auch die privaten Mitglieder, die jedoch durch eine Konvention klar von der öffentlichen API getrennt sind, z. B. indem Sie ihnen ein Präfix voranstellen
_
oder sie unter einem einzelnen privaten Objekt verschachteln .quelle
Zu diesem Zweck habe ich ein npm-Paket erstellt, das Sie möglicherweise nützlich finden: require-from
Grundsätzlich legen Sie nicht öffentliche Methoden offen, indem Sie:
Hinweis:
testExports
kann ein beliebiger gültiger Name sein, außerexports
natürlich.Und aus einem anderen Modul:
quelle
requireFrom
mit den richtigen Parametern aufrufen .) Wenn das Modul mittextExports
durch einenrequire
Aufruf geladen wird , bevorrequireFrom
es geladen wird ,requireFrom
wird es zurückgegebenundefined
. (Ich habe es gerade getestet.) Obwohl es oft möglich ist, die Ladereihenfolge von Modulen zu steuern, ist dies nicht immer praktisch. (Wie einige Mokka-Fragen zu SO belegen.) Diese Lösung funktioniert im Allgemeinen auch nicht mit AMD-Modulen. (Ich lade AMD-Module täglich in Node zum Testen.)Ich habe eine zusätzliche Funktion hinzugefügt, die ich Internal () nenne und von dort aus alle privaten Funktionen zurückgebe. Diese Internal () -Funktion wird dann exportiert. Beispiel:
Sie können die internen Funktionen folgendermaßen aufrufen:
Diese Lösung gefällt mir am besten, weil:
quelle
Ich folgte der Antwort von @barwin und überprüfte, wie Unit-Tests mit Rewire durchgeführt werden können Modul durchgeführt werden können. Ich kann bestätigen, dass diese Lösung einfach funktioniert.
Das Modul sollte aus zwei Teilen bestehen - dem öffentlichen und dem privaten. Für öffentliche Funktionen können Sie dies auf standardmäßige Weise tun:
Für den privaten Bereich:
Um mehr über das Thema zu erfahren, habe ich ein Arbeitsbeispiel mit vollständigen Modultests erstellt. Das Testen umfasst den privaten und öffentlichen Bereich.
Für weitere Informationen empfehle ich Ihnen, den Artikel ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ) zu lesen, der das Thema vollständig beschreibt und Codebeispiele enthält.
quelle
Ich weiß, dass dies nicht unbedingt die Antwort ist, nach der Sie suchen, aber ich habe festgestellt, dass es sich die meiste Zeit, wenn eine private Funktion getestet werden sollte, lohnt, in einer eigenen Datei zu sein.
ZB anstatt private Methoden in derselben Datei wie die öffentlichen zu haben, wie diese ...
src / thing / PublicInterface.js
... du hast es so aufgeteilt:
src / thing / PublicInterface.js
src / thing / internal / helper1.js
src / thing / internal / helper2.js
Auf diese Weise können Sie problemlos testen
helper1
undhelper2
unverändert, ohne Rewire und andere "Magie" zu verwenden (die, wie ich festgestellt habe, ihre eigenen Schwachstellen beim Debuggen haben oder wenn Sie versuchen, auf TypeScript umzusteigen, ganz zu schweigen von schlechteren Verständlichkeit für neue Kollegen). Und wenn sie sich in einem Unterordner namensinternal
oder so ähnlich befinden, können Sie verhindern, dass sie versehentlich an unbeabsichtigten Orten verwendet werden.PS: Ein weiteres häufiges Problem mit „privaten“ Methoden ist , dass , wenn Sie testen mögen ,
publicMethod1
undpublicMethod2
und die Helfer verspotten, wieder, Sie in der Regel so etwas wie Rewire brauchen , das zu tun. Wenn sie sich jedoch in separaten Dateien befinden, können Sie Proxyquire verwenden, was im Gegensatz zu Rewire keine Änderungen an Ihrem Erstellungsprozess erfordert, einfach zu lesen und zu debuggen ist und auch mit TypeScript gut funktioniert.quelle
Um private Methoden zum Testen verfügbar zu machen, mache ich Folgendes:
quelle