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


71

AngularJS v1.2.26

茉莉花v2.2.0

如何更改或删除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);

          ...

        });
    });

...

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

我该怎么做呢?


Answers:


89

您可以覆盖它

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

4
有办法完全清除间谍吗?要返回原始功能?
emersonthis 2015年

4
最大的问题是,如果您在每次测试中都没有相同的功能,那么为什么根本就没有全球间谍?如果要为每个测试设置间谍,请为每个测试设置间谍。
1

13
@Jan如果我有五十个测试,而其中只有一个具有与其他功能不同的功能的间谍,我宁愿只在其中一次更改它,而不是每一个测试。
theblang

1
好吧,就我而言,它在一个全局对象(由本机代码定义)上。因此,我有多种规格,需要在不同情况下返回不同的值
。...– FlavorScape

它会通过调用jasmine.createSpy()。and.callThrought()返回到其原始实现吗?
aj去

29

您可以覆盖间谍的返回值

    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
作品将于18/6/2019
George

如果您所有的代码都在相同的描述中,则可能会起作用,但否则不会因为未定义getUpdateSpy ...
GarfieldKlon

@GarfieldKlon您可以通过getUpdateSpy在父describe块中定义变量来解决此问题。
塞缪尔·布什

23

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

jasmine.getEnv().allowRespy(true);

spyOn()当您不需要和/或有权访问第一个间谍时,您将可以多次呼叫。请注意,如果已有间谍活动,它将返回前一个间谍。

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


老实说,这是我多年来寻找的答案。我希望它在互联网上更加普遍。一百万感谢:)
Novastorm



2

绿色的对勾标记的答案对我不起作用,但这确实可行:

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

您的茉莉花测试将运行,但是当您启动程序时,如果您没有将随机字符串和空函数用作args,则您的应用程序打字稿将大吼大叫createSpy()


1
这可能是由于茉莉花的更新版本。我正在使用2.7,这对我有效。
MBielski '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.