【问题标题】:Angular unit testing with Jasmine: how to remove or modify spyOn使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn
【发布时间】:2023-04-03 19:35:01
【问题描述】:

AngularJS v1.2.26

茉莉花v2.2.0

如何更改或删除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 时,测试不起作用。

我该怎么做?

【问题讨论】:

标签: javascript angularjs unit-testing jasmine karma-jasmine


【解决方案1】:

你可以覆盖它

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

【讨论】:

  • 有没有办法完全删除间谍?回到原来的功能?
  • 最大的问题是,如果您在每个测试中都没有相同的功能,那为什么还要设置全局间谍呢?如果要为每个测试设置 spy,则为每个测试设置 spy。
  • @Jan 如果我有 50 个测试,并且其中只有一个具有与其他功能不同的功能的间谍,我宁愿只在那里更改一次,而不是每次测试.
  • 好吧,就我而言,它位于全局对象(由本机代码定义)上。所以我有多个规范需要在不同的情况下返回不同的值......
  • 会不会通过调用 jasmine.createSpy().and.callThrought() 回到原来的实现?
【解决方案2】:

你可以覆盖间谍的返回值

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

【讨论】:

  • 工作于 18/6/2019
  • 如果您的所有代码都在同一个描述中,这可能会起作用,但否则不会因为未定义 getUpdateSpy...
  • @GarfieldKlon 您可以通过在父 describe 块中定义变量 getUpdateSpy 来解决此问题。
【解决方案3】:

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

jasmine.getEnv().allowRespy(true);

当您不想和/或无法接触到第一个间谍时,您可以多次致电spyOn()。注意它会返回之前的间谍(如果有的话)。

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

【讨论】:

  • 老实说,这是我多年来一直在寻找的答案。我希望它在互联网上更流行。一百万谢谢:)
【解决方案4】:

更简单的方法:

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

它会返回值。

【讨论】:

  • 谢谢。其他人都错过了明显的答案。
  • 您的类型系统似乎没有抱怨。这就引出了一个问题:为什么要使用 Typescript?
【解决方案5】:

另一种选择:

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

【讨论】:

    【解决方案6】:

    绿色复选标记的答案对我不起作用,但确实如此:

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

    您的 jasmine 测试将运行,但是当您启动应用程序时,如果您不将随机字符串和空函数作为 args 放入 createSpy(),您的应用程序打字稿会大声对您大喊大叫。

    【讨论】:

    • 这可能是由于更新了 Jasmine 版本。我正在使用 2.7,这对我有用。
    猜你喜欢
    • 2020-04-10
    • 2016-03-29
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    相关资源
    最近更新 更多