Javascript 使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28821511/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:28:11  来源:igfitidea点击:

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

javascriptangularjsunit-testingjasminekarma-jasmine

提问by emersonthis

AngularJS v1.2.26

AngularJS v1.2.26

Jasmine v2.2.0

茉莉花 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

如何更改或删除 a 的行为spyOn?当我尝试覆盖它时,出现以下错误: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.

当我删除第二个 spyOn 时,测试不起作用。

How do I do this?

我该怎么做呢?

回答by Peter Ashwell

You can just overwrite it

你可以覆盖它

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

回答by Javier Candalaft-CONT

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

回答by André Werlang

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

从 jasmine v2.5 开始,使用全局allowRespy()设置。

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()当您不想和/或有权访问第一个间谍时,您将能够多次呼叫。当心它会返回之前的间谍,如果任何已经处于活动状态。

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

回答by Aniruddha Das

More easier way is to simple

更简单的方法是简单

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

回答by rb1econ

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().

您的 jasmine 测试将运行,但是当您启动时,如果您不将随机字符串和空函数作为 args 放置到createSpy().

回答by Justas

Another option:

另外一个选项:

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