Angular unit testing with Jasmine: how to remove or modify spyOn

AngularJS v1.2.26

Jasmine v2.2.0

How can I change or remove the behavior of a spyOn? When I try to override it, I get the following error: 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);


...


});
});


...

When I remove the second spyOn the test doesn't work.

How do I do this?

57034 次浏览

You can just overwrite it

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

You can override the return value of the spy

    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);

the green check-marked answer didn't work for me, but this did:

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

your jasmine test will run but when you go to fire up your app typescript will yell loudly at you if you don't put a random string and an empty function as the args to createSpy().

More easier and simpler way:

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

It will return the value.

Since jasmine v2.5, use the global allowRespy() setting.

jasmine.getEnv().allowRespy(true);

You'll be able to call spyOn() multiple times, when you don't want and/or have access to the first spy. Beware it will return the previous spy, if any is already active.

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

Another option:

(yourService.method as jasmine.Spy).and.returnValue(value);