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

52,816

Solution 1

You can just overwrite it

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

Solution 2

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

Solution 3

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

Solution 4

More easier and simpler way:

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

It will return the value.

Solution 5

Another option:

(yourService.method as jasmine.Spy).and.returnValue(value);
Share:
52,816

Related videos on Youtube

emersonthis
Author by

emersonthis

I am a designer, developer, and problem solver. I make websites and stuff. I work with brazen startups, modest individuals, earnest small business, and everyone in between. I care as much about how things look as how they work. I enjoy writing and teaching what I know. The best part about my job is constantly learning new things.

Updated on July 31, 2021

Comments

  • emersonthis
    emersonthis almost 3 years

    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?

  • emersonthis
    emersonthis about 9 years
    Is there way to remove the spy entirely? To go back to the original function?
  • Jan
    Jan almost 9 years
    The big question is, if you don't the same functionality in every test, why have a global spy at all? If you want to set the spy for every test, then set the spy for every test.
  • theblang
    theblang almost 8 years
    @Jan If I have fifty tests, and only one of them has a spy for a function that is different from the rest, I'd rather just change it the one time there instead of every single test.
  • FlavorScape
    FlavorScape about 7 years
    well, in my case it's on a global object (defined by native code). So I have multiple specs that need to return different values in different situations....
  • MBielski
    MBielski over 6 years
    This is probably due to an updated version of Jasmine. I am using 2.7 and this works for me.
  • camleng
    camleng over 5 years
    Thank you. Everyone else is missing the obvious answer.
  • George C.
    George C. almost 5 years
    Works on 18/6/2019
  • Novastorm
    Novastorm almost 5 years
    Honestly, this is the answer I've been looking for ages. I wish it was more prevalent on the internet. A million thanks :)
  • GarfieldKlon
    GarfieldKlon over 4 years
    That may work if all your code is in the same describe, but otherwise not because getUpdateSpy is not defined...
  • aj go
    aj go over 3 years
    would it return to its original implementation by calling jasmine.createSpy().and.callThrought()?
  • Samuel Bushi
    Samuel Bushi over 3 years
    @GarfieldKlon You can work around that by defining the variable getUpdateSpy in the parent describe block.
  • ANeves
    ANeves about 3 years
    It seems that your type system is not complaining. That begs the question: why use Typescript at all?