Ist es möglich, die Spyon-Methode des Jasmine Unit Testing Frameworks für private Methoden einer Klasse zu verwenden?
Die Dokumentation gibt dieses Beispiel, aber kann dies für eine private Funktion flexibel sein?
describe("Person", function() {
it("calls the sayHello() function", function() {
var fakePerson = new Person();
spyOn(fakePerson, "sayHello");
fakePerson.helloSomeone("world");
expect(fakePerson.sayHello).toHaveBeenCalled();
});
});
javascript
unit-testing
jasmine
user502014
quelle
quelle
spyOn(fakePerson as any, 'sayHello');
<any>
, damit dies funktioniert?<any>
die Typprüfung gelöscht , sodass keine Fehler bei der Kompilierungszeit von TypeScript (und keine Fehler in Ihrem Editor) auftreten. Der TypeSciprt wird jedoch letztendlich in Javascript kompiliert, wo jede Methode öffentlich ist, sodass die Typescript-Fehler gelöscht werden.Angenommen, es
sayHello(text: string)
ist eine private Methode. Sie können den folgenden Code verwenden:// Create a spy on it using "any" spyOn<any>(fakePerson, 'sayHello').and.callThrough(); // To access the private (or protected) method use [ ] operator: expect(fakeperson['sayHello']).toHaveBeenCalledWith('your-params-to-sayhello');
any
.[]
Operator, um auf die private (oder geschützte) Methode zuzugreifen .quelle
sayHello
ist eine private Methode. und die erste Zeile ist, wie man einen Spion darauf erstellt. Die zweite Zeile ist der Test.<any>
Tag. Deshalb war ich verwirrt.spyOn<any>(fakePerson, 'sayHello'); expect(fakePerson['sayHello']).toHaveBeenCalled();
Durch Hinzufügen
<any>
zu spyOn entfernen Sie es aus der Typoskript-Typprüfung. Sie müssen auch die Array-Indexnotation verwenden, um auf eine private Methode (sayHello) in der Testerwartung zuzugreifenquelle
Wenn Sie Typescript für Ihre Objekte verwenden, ist die Funktion nicht wirklich privat.
Sie müssen lediglich den vom
spyOn
Aufruf zurückgegebenen Wert speichern und dann seinecalls
Eigenschaft abfragen .Am Ende sollte dieser Code für Sie gut funktionieren (zumindest für mich):
describe("Person", function() { it("calls the sayHello() function", function() { var fakePerson = new Person(); // save the return value: var spiedFunction = spyOn<any>(fakePerson, "sayHello"); fakePerson.helloSomeone("world"); // query the calls property: expect(spiedFunction.calls.any()).toBeFalsy(); }); });
quelle
Error:(33, 56) TS2345:Argument of type '"sayHello"' is not assignable to parameter of type '"sayGoodbye"'.
wobeisayGoodbye
eine öffentliche Methode aktiviertPerson
undsayGoodbye
privat ist. Ich muss es auf jeden übertragen ("sayHello" wie jeden)person["sayHello"]
stattperson.sayHello
(wenn Sie das tun). Dies ist keine bewährtespy<any>
kann in der Tat die richtige Antwort sein. DankeIn meinem Fall (Typoskript):
jest.spyOn<any, string>(authService, 'isTokenActual')
ODER mit verspottetem Ergebnis:
jest.spyOn<any, string>(authService, 'isTokenActual').mockImplementation(() => { return false; });
quelle
Kein Grund, warum Sie nicht auf eine private Funktion außerhalb des Kontexts Ihrer Instanz zugreifen können.
Übrigens ist es keine gute Idee, Objekte auszuspionieren, die Sie testen möchten. Wenn Sie testen, ob eine bestimmte Methode in Ihrer Klasse, die Sie testen möchten, aufgerufen wird, sagt dies nichts aus. Nehmen wir an, Sie haben den Test geschrieben und er ist bestanden. Zwei Wochen später überarbeiten Sie einige Dinge in der Funktion und fügen einen Fehler hinzu. Ihr Test ist also immer noch grün, weil Sie die Funktion aufgerufen haben. B.
Spione sind nützlich, wenn Sie mit Dependency Injection arbeiten , bei dem alle externen Abhängigkeiten vom Konstruktor übergeben und nicht in Ihrer Klasse erstellt werden. Nehmen wir also an, Sie haben eine Klasse, die ein dom-Element benötigt. Normalerweise würden Sie einen jquery-Selektor in der Klasse verwenden, um dieses Element abzurufen. Aber wie wollen Sie testen, ob etwas mit diesem Element gemacht wird? Sicher können Sie es zu Ihren Testseiten HTML hinzufügen. Sie können Ihre Klasse aber auch aufrufen, indem Sie das Element im Konstruktor übergeben. Auf diese Weise können Sie mit spy überprüfen, ob Ihre Klasse wie erwartet mit diesem Element interagiert.
quelle
Typoskript wird zu Javascript kompiliert und in Javascript ist jede Methode öffentlich. Sie können also die Array-Indexnotation verwenden, um auf private Methoden oder Dateien zuzugreifen, nämlich:
Object['private_field']
quelle
Wenn Sie private Funktionen innerhalb einer Klasse testen möchten, fügen Sie Ihrer Klasse einen Konstruktor hinzu, der signalisiert, dass diese privaten Funktionen zurückgegeben werden.
Lesen Sie dies durch, um zu sehen, was ich meine: http://iainjmitchell.com/blog/?p=255
Ich habe eine ähnliche Idee verwendet und bis jetzt funktioniert es großartig!
quelle
const spy = spyOn<any>(component, 'privateMethod'); expect(spy).toHaveBeenCalled();
Erstellen Sie eine lokale Konstante des Spionageobjekts, um Flusenwarnungen bezüglich des Objektzugriffs über Zeichenfolgenliterale zu vermeiden.
quelle