gpt4 book ai didi

javascript - 在 Angular 单元测试中,如何清理 $timeout promise ,以免它们持续存在?

转载 作者:行者123 更新时间:2023-11-30 16:27:48 25 4
gpt4 key购买 nike

我有一系列的单元测试。其中一个 Controller 正在设置一个 $timeout promise ,每 1000 毫秒执行一次(它调用自己的函数,因此它的行为类似于 $interval,只要正在查看 Controller ,它就会继续每 1 秒执行一次).然而,当 Controller 被销毁(用户导航到另一个 View )时,$timeout.cancel 被准确调用,因此自调用停止继续。

但是在运行单元测试时,出于某种原因在执行此 Controller 的测试后,永远不会触发 $destroy。

因此,当运行第二个单元测试时(在本例中为指令的单元测试),它也使用 $timeout.flush(...),它会激活 $timeout promise未关联的 Controller !

但我不知道如何在其单元测试完成后强制 Controller $destroy,或者如何在开始其他单元测试之前更改 $timeout 以删除/取消所有 promise 。

结果,它导致两个单元测试之间发生冲突,其中一个单元测试出现意外行为导致失败。

有什么建议吗?

[编辑] 解决方案:通过将 scope.$destroy() 添加到我们所有的 Controller 和指令单元测试中,我们将单元测试执行时间从 30 秒缩短为6秒!并且 $timeout 冲突不再出现。

afterEach(function () { 
scope.$destroy(); //directive, or controller: $scope.$destroy();
});

最佳答案

我建议避免在单元测试时创建真正的超时。这将需要在实例化 Controller 时注入(inject) $timeout 服务的模拟,但在单元测试期间基于超时提供对异步操作的更多控制。在不需要测试超时回调的最简单情况下,$timeout mock 可以非常简单(示例使用 Jasmine):

describe('MainCtrl', function() {
var $scope = null;
var ctrl = null;
var mockedTimeout = function() {
console.log('Timeout is mocked');
}
mockedTimeout.cancel = function() {
console.log('Timeout is cancelled');
}

beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();

ctrl = $controller('MainCtrl', {
$scope: $scope,
$timeout: mockedTimeout
});
}));
});

这里是 plunker显示了正在运行的完整测试设置

关于javascript - 在 Angular 单元测试中,如何清理 $timeout promise ,以免它们持续存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33837766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com