I have a small Angular service that implements asynchronous rate-limiting for other functions, similar to this sample. Given that the core purpose of this class is to manage asynchronous behaviors, I need to test it in an asynchronous manner - purely synchronous tests won't suffice to validate its functionality.
As far as I understand, when Angular's ngMock
module is used, the built-in $timeout
service is substituted with a mocked version of $timeout
, enabling tests to synchronously execute functions that are normally asynchronous. However, in this scenario, I want to utilize the actual implementation of $timeout
instead of the mocked version.
Is there a way to inject the real implementation of $timeout
into my unit test?
Currently, this is how my tests are structured (I'm coding in TypeScript):
describe('My Tests', () => {
let myService: MyService,
$timeout: ng.ITimeoutService;
beforeEach(() => {
inject(($injector) => {
// this retrieves the mocked version of $timeout
$timeout = $injector.get('$timeout');
});
myService = new MyService($timeout);
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
});
it('should succeed', (done) => {
$timeout(50)
.then(() => {
// this assertion is never reached
expect(1).toBe(1);
})
.finally(done);
});
});
Upon running this test, Karma raises a complaint about the excessive duration since the mocked $timeout
service doesn't initiate the deferred timeout as expected:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.