Ich habe ein AMD-Modul, das ich testen möchte, aber ich möchte seine Abhängigkeiten verspotten, anstatt die tatsächlichen Abhängigkeiten zu laden. Ich verwende requirejs und der Code für mein Modul sieht ungefähr so aus:
define(['hurp', 'durp'], function(Hurp, Durp) {
return {
foo: function () {
console.log(Hurp.beans)
},
bar: function () {
console.log(Durp.beans)
}
}
}
Wie kann ich mich verspotten hurp
und durp
so effektiv Unit-Tests durchführen?
javascript
unit-testing
mocking
requirejs
Jergason
quelle
quelle
define
Funktion zu verspotten . Es gibt jedoch einige verschiedene Optionen. Ich werde eine Antwort in der Hoffnung posten, dass es hilfreich sein wird.Antworten:
Nachdem ich diesen Beitrag gelesen hatte, kam ich auf eine Lösung, die die Funktion requirejs config verwendet, um einen neuen Kontext für Ihren Test zu erstellen, in dem Sie einfach Ihre Abhängigkeiten verspotten können:
So wird ein neuer Kontext erstellt, in dem die Definitionen für
Hurp
undDurp
von den Objekten festgelegt werden, die Sie an die Funktion übergeben haben. Das Math.random für den Namen ist vielleicht etwas schmutzig, aber es funktioniert. Wenn Sie eine Reihe von Tests durchführen müssen, müssen Sie für jede Suite einen neuen Kontext erstellen, um die Wiederverwendung Ihrer Mocks zu verhindern, oder Mocks laden, wenn Sie das eigentliche requirejs-Modul benötigen.In Ihrem Fall würde es so aussehen:
Daher verwende ich diesen Ansatz für eine Weile in der Produktion und er ist wirklich robust.
quelle
createContext
Funktion übergeben. Wenn Sie in Ihrem Fall nur{hurp: 'hurp'}
an function übergeben, wird diedurp
Datei als normale Abhängigkeit geladen.Vielleicht möchten Sie sich die neue Squire.js-Bibliothek ansehen
aus den Dokumenten:
Squire.js ist ein Abhängigkeitsinjektor für Require.js-Benutzer, um das Verspotten von Abhängigkeiten zu vereinfachen!
quelle
Ich habe drei verschiedene Lösungen für dieses Problem gefunden, von denen keine angenehm ist.
Abhängigkeiten inline definieren
Fugly. Sie müssen Ihre Tests mit viel AMD Boilerplate überladen.
Laden von Mock-Abhängigkeiten aus verschiedenen Pfaden
Dazu wird eine separate Datei config.js verwendet, um Pfade für jede der Abhängigkeiten zu definieren, die auf Mocks anstelle der ursprünglichen Abhängigkeiten verweisen. Dies ist auch hässlich und erfordert die Erstellung von Tonnen von Testdateien und Konfigurationsdateien.
Fake It In Node
Dies ist meine derzeitige Lösung, aber immer noch eine schreckliche.
Sie erstellen Ihre eigene
define
Funktion, um dem Modul eigene Mocks bereitzustellen und Ihre Tests in den Rückruf aufzunehmen. Dann haben Sieeval
das Modul, um Ihre Tests auszuführen, wie folgt:Dies ist meine bevorzugte Lösung. Es sieht ein wenig magisch aus, hat aber einige Vorteile.
eval
Wut einsetzen und sich vorstellen, wie Crockford vor Wut explodiert.Es hat natürlich immer noch einige Nachteile.
define
in jedem Test verspotten , da dort Ihre Tests tatsächlich ausgeführt werden.Ich arbeite an einem Testläufer, um eine schönere Syntax für diese Art von Sachen zu geben, aber ich habe immer noch keine gute Lösung für Problem 1.
Fazit
Das Verspotten von Deps in Requirements ist hart. Ich habe einen Weg gefunden, der irgendwie funktioniert, bin aber immer noch nicht sehr zufrieden damit. Bitte lassen Sie mich wissen, wenn Sie bessere Ideen haben.
quelle
Es gibt eine
config.map
Option http://requirejs.org/docs/api.html#config-map .Wie man es benutzt:
RequireJS genau konfigurieren;
In diesem Fall können Sie für Normal- und Testcode das
foo
Modul verwenden, das eine echte Modulreferenz darstellt und entsprechend stub.quelle
Sie können testr.js verwenden , um Abhängigkeiten zu verspotten. Sie können testr so einstellen, dass die Scheinabhängigkeiten anstelle der ursprünglichen geladen werden. Hier ist ein Anwendungsbeispiel:
Überprüfen Sie dies auch: http://cyberasylum.janithw.com/mocking-requirejs-dependencies-for-unit-testing/
quelle
Diese Antwort basiert auf der Antwort von Andreas Köberle .
Es war nicht so einfach für mich, seine Lösung zu implementieren und zu verstehen, deshalb werde ich sie etwas detaillierter erklären, wie sie funktioniert, und einige Fallstricke vermeiden, in der Hoffnung, dass sie zukünftigen Besuchern helfen wird.
Also zuerst das Setup:
Ich benutze Karma als Testläufer und MochaJs als Testframework .
Die Verwendung von Squire hat bei mir aus irgendeinem Grund nicht funktioniert. Als ich es verwendete, warf das Testframework Fehler auf:
RequireJs bietet die Möglichkeit, Modul-IDs anderen Modul-IDs zuzuordnen . Außerdem können Sie eine
require
Funktion erstellen , die eine andere Konfiguration als die globale verwendetrequire
.Diese Funktionen sind für das Funktionieren dieser Lösung von entscheidender Bedeutung.
Hier ist meine Version des Scheincodes, einschließlich (vieler) Kommentare (ich hoffe, es ist verständlich). Ich habe es in ein Modul eingewickelt, damit die Tests es leicht erfordern können.
Die größte Gefahr, auf die ich gestoßen bin und die mich buchstäblich Stunden gekostet hat, war das Erstellen der RequireJs-Konfiguration. Ich habe versucht, es (tief) zu kopieren und nur die erforderlichen Eigenschaften (wie Kontext oder Karte) zu überschreiben. Das funktioniert nicht! Kopieren Sie nur die
baseUrl
, das funktioniert gut.Verwendung
Um es zu verwenden, benötigen Sie es in Ihrem Test, erstellen Sie die Mocks und übergeben Sie es dann an
createMockRequire
. Beispielsweise:Und hier ein Beispiel für eine vollständige Testdatei :
quelle
Wenn Sie einige einfache JS-Tests durchführen möchten, die eine Einheit isolieren, können Sie einfach dieses Snippet verwenden:
quelle