使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn
Posted
技术标签:
【中文标题】使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn【英文标题】:Angular unit testing with Jasmine: how to remove or modify spyOn 【发布时间】:2015-05-03 11:55:14 【问题描述】: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 时,测试不起作用。
我该怎么做?
【问题讨论】:
Jasmine SpyOn same method more than once的可能重复 【参考方案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,这对我有用。以上是关于使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jasmine 进行 Angular 单元测试:如何删除或修改 spyOn
使用 jasmine / karma 进行 Angular 4 单元测试和 http post mocking - 如何修复
使用 Karma Jasmine 的 Angular 1.5 组件模板单元测试