Angular Unit Testing mit Jasmine: Entfernen oder Ändern von SpyOn


71

AngularJS v1.2.26

Jasmine v2.2.0

Wie kann ich das Verhalten von a ändern oder entfernen spyOn? Wenn ich versuche, es zu überschreiben, wird folgende Fehlermeldung angezeigt:Error: getUpdate has already been spied upon

var data1 = 'foo';
var data2 = 'bar';

describe("a spec with a spy", function(){

    beforeEach(module('app'));

    var $q;

    beforeEach(inject(function(_updateService_, _$q_){
        updateService = _updateService_;

        //spy the results of the getUpdate()
        $q = _$q_;
        var deferred = $q.defer();
        deferred.resolve( data1 );
        spyOn(updateService, 'getUpdate').and.returnValue(deferred.promise);

    }));

    describe('and here the spy should be different', function() {

        it('returns a different value', function() {

          var deferred = $q.defer();
          deferred.resolve( data2 );
          spyOn(updateService, 'getUpdate'); //ERROR HERE
          updateService.getUpdate.and.returnValue(deferred.promise);

          ...

        });
    });

...

Wenn ich den zweiten SpyOn entferne, funktioniert der Test nicht.

Wie mache ich das?


Antworten:


89

Sie können es einfach überschreiben

updateService.getUpdate = jasmine.createSpy().and.returnValue(etc)

4
Gibt es eine Möglichkeit, den Spion vollständig zu entfernen? Um zur ursprünglichen Funktion zurückzukehren?
Emersonthis

4
Die große Frage ist, wenn Sie nicht in jedem Test die gleiche Funktionalität haben, warum überhaupt einen globalen Spion? Wenn Sie den Spion für jeden Test festlegen möchten, legen Sie den Spion für jeden Test fest.
Januar

13
@Jan Wenn ich fünfzig Tests habe und nur einer von ihnen einen Spion für eine Funktion hat, die sich von den anderen unterscheidet, würde ich sie lieber nur einmal dort ändern, anstatt bei jedem einzelnen Test.
Theblang

1
In meinem Fall handelt es sich um ein globales Objekt (definiert durch nativen Code). Ich habe also mehrere Spezifikationen, die in verschiedenen Situationen unterschiedliche Werte zurückgeben müssen ...
FlavorScape

Würde es durch Aufrufen von jasmine.createSpy (). and.callThrought () zu seiner ursprünglichen Implementierung zurückkehren?
Aj gehen

29

Sie können den Rückgabewert des Spions überschreiben

    var deferred = $q.defer();
    deferred.resolve( data1 );

    var getUpdateSpy = spyOn(updateService, 'getUpdate').and.returnValue(deferred.promise);



    var newDeferred = $q.defer();
    newDeferred.resolve( data2 );

    getUpdateSpy.and.returnValue(newDeferred.promise);        

1
Arbeiten am 18.6.2019
George C.

Das kann funktionieren, wenn Ihr gesamter Code in der gleichen Beschreibung ist, aber ansonsten nicht, weil getUpdateSpy nicht definiert ist ...
GarfieldKlon

@GarfieldKlon Sie können dies umgehen, indem Sie die Variable getUpdateSpyim übergeordneten describeBlock definieren.
Samuel Bushi

23

Verwenden Sie seit Jasmin v2.5 die globale allowRespy()Einstellung.

jasmine.getEnv().allowRespy(true);

Sie können spyOn()mehrmals anrufen , wenn Sie nicht möchten und / oder Zugriff auf den ersten Spion haben. Beachten Sie, dass der vorherige Spion zurückgegeben wird, falls einer bereits aktiv ist.

spyOn(updateService, 'getUpdate').and.returnValue(deferred.promise);
...
spyOn(updateService, 'getUpdate').and.returnValue(deferred.promise);


Ehrlich gesagt, das ist die Antwort, nach der ich seit Ewigkeiten gesucht habe. Ich wünschte, es wäre im Internet häufiger anzutreffen. Eine Million danke :)
Novastorm

8

Einfacher geht es zu einfach

updateService.getUpdate.and.returnValue(Observable.of({status:true}));

Vielen Dank. Allen anderen fehlt die offensichtliche Antwort.
Camleng


2

Die Antwort mit dem grünen Häkchen hat bei mir nicht funktioniert, aber das hat funktioniert:

yourCoolService.createThing = jasmine.createSpy('notreal', function(){}).and.returnValue();

Ihr Jasmin-Test wird ausgeführt, aber wenn Sie das App-Typoskript starten, werden Sie laut angeschrien, wenn Sie keine zufällige Zeichenfolge und keine leere Funktion als Argumente verwenden createSpy().


1
Dies ist wahrscheinlich auf eine aktualisierte Version von Jasmine zurückzuführen. Ich benutze 2.7 und das funktioniert bei mir.
MBielski
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.