>我有一个小型的 Angular 服务来处理其他函数的异步速率限制,类似于此示例。 由于此类的主要目的是调节异步行为,因此我希望能够异步测试此服务 - 我将无法证明此类正在使用纯同步测试。
如果我理解正确,当加载 Angular 的 ngMock
模块时,内置的 $timeout
服务被替换为模拟版本的$timeout
,该版本允许测试同步运行通常异步的函数。 但是,在这种情况下,我想使用 $timeout
的真正实现而不是模拟版本。
如何将$timeout
的真正实现注入到我的单元测试中?
以下是我的测试目前的样子(我正在用 TypeScript 编写我的测试(:
describe('My Tests', () => {
let myService: MyService,
$timeout: ng.ITimeoutService;
beforeEach(() => {
inject(($injector) => {
// this gets me the mocked version of $timeout
$timeout = $injector.get('$timeout');
});
myService = new MyService($timeout);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
});
it('should pass', (done) => {
$timeout(50)
.then(() => {
// this is never called
expect(1).toBe(1);
})
.finally(done);
});
});
当我运行这个测试时,Karma 抱怨测试也花了很长时间,因为模拟的$timeout
服务实际上从未启动其延迟超时:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
你需要调用 $timeout.flush((; 强制释放控制器内的所有$timeout:
it('a ctrl with $timeout inside', inject(function($timeout) {
var myCOntroller = $controller('Controller', { $scope: $scope });
// flush timeout(s) for all code under test.
$timeout.flush();
// this will throw an exception if there are any pending timeouts.
$timeout.verifyNoPendingTasks();
expect($scope.result).toBe("whatIexpect");
}));
// with your example
it('should pass', (done) => {
$timeout(50)
.then(() => {
// this is never called
expect(1).toBe(1);
})
.finally(done);
$timeout.flush();
});
一切都在这里更好地解释:)
此外,您永远不应该使用真正的$timeout因为它确实会减慢您的测试速度......