Spies, Async Testing & the Ecosystem
Spies — Built-in Mocking
spyOn(userRepo, 'findById').and.returnValue({ id: 1, name: 'Ada' });
spyOn(logger, 'log').and.callThrough(); // still runs the real logger too
spyOn(emailService, 'send').and.callFake(() => Promise.resolve());
expect(userRepo.findById).toHaveBeenCalledWith(1);
// standalone spy, e.g. for a callback argument
const onComplete = jasmine.createSpy('onComplete');
runTask(onComplete);
expect(onComplete).toHaveBeenCalled();
// fake a whole dependency with several methods at once
const mockService = jasmine.createSpyObj('UserService', ['getUser', 'saveUser']);This built-in spy support is Jasmine's equivalent of what Sinon.js provides for Mocha — no separate mocking library required.
Mocking Time
beforeEach(() => jasmine.clock().install());
afterEach(() => jasmine.clock().uninstall());
it('calls the callback after 5 seconds', () => {
const callback = jasmine.createSpy();
setTimeout(callback, 5000);
jasmine.clock().tick(5001); // instantly "fast-forward", no real waiting
expect(callback).toHaveBeenCalled();
});Async Matchers
it('resolves with the user', async () => {
await expectAsync(fetchUser(1)).toBeResolvedTo({ id: 1, name: 'Ada' });
});Jasmine + Karma, and the Jest Connection
Jasmine is the testing framework (structure, assertions, spies); Karma is a separate test runner that launches real browsers and executes the Jasmine specs in them — Angular's CLI historically defaulted to this pairing. Jest's syntax was heavily inspired by Jasmine's describe/it/expect pattern, adding a built-in runner, coverage, and snapshot testing on top.
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free