Jasmine is the default framework adapter for the vast majority of Karma projects, especially those originating from the Angular CLI. This lesson covers setup, syntax, and Jasmine-specific features like spies and randomized order.
Setting Up karma-jasmine
karma-jasmine is a thin bridge that injects Jasmine's global functions (describe, it, expect, beforeEach, and more) into the browser page Karma generates. jasmine-core provides the actual implementation of those functions and their matchers.
Once configured, every spec file can use describe, it, and expect as browser globals, with no explicit import needed.
Jasmine Test Syntax
describe('Calculator', function() {
let calc;
beforeEach(function() {
calc = new Calculator();
});
it('adds two numbers', function() {
expect(calc.add(2, 3)).toBe(5);
});
it('throws on invalid input', function() {
expect(function() { calc.add('a', 3); }).toThrow();
});
});
describe() groups related specs under a shared label; it() defines a single spec.
beforeEach()/afterEach() run before/after every spec in the enclosing describe() block.
expect(value).matcher() is Jasmine's assertion syntax — matchers include .toBe(), .toEqual(), .toThrow(), and more.
Jasmine has no external assertion dependency — everything shown here ships in jasmine-core.
Jasmine Matchers Cheat Sheet
The matchers used in the overwhelming majority of everyday Jasmine specs.
Matcher
Checks
.toBe(x)
Strict equality (===)
.toEqual(x)
Deep equality for objects/arrays
.toBeTruthy() / .toBeFalsy()
General truthy/falsy checks
.toBeNull() / .toBeDefined()
Exact null/defined checks
.toContain(x)
Array or string contains a value
.toThrow(err?)
Function throws when called
.toHaveBeenCalled()
A spy was called at least once
.toHaveBeenCalledWith(...)
A spy was called with specific arguments
Jasmine Spies for Mocking
Jasmine includes its own spy system — spyOn() wraps an existing method on an object, tracking calls and optionally overriding its behavior, without needing a separate mocking library like Sinon.
spyOn() restores the original method automatically after each spec, keeping specs isolated.
Writing Asynchronous Jasmine Specs
Modern Jasmine (used by karma-jasmine) supports async/await directly in spec callbacks, in addition to the older done callback style still seen in many legacy Karma suites.
it('resolves with user data', async function() {
const user = await fetchUser(1);
expect(user.name).toBe('Ada');
});
// Older, still-supported callback style:
it('resolves with user data (done style)', function(done) {
fetchUser(1).then(function(user) {
expect(user.name).toBe('Ada');
done();
});
});
Prefer async/await in new specs; recognize the done callback pattern when reading older ones.
Common Mistakes
Forgetting to call done() in callback-style async specs, causing Jasmine to time out instead of failing clearly.
Using .toBe() for object/array comparisons where .toEqual() is what's actually needed.
Not resetting spies between specs when spyOn()'s automatic restoration isn't enough for more complex mocking.
Mixing Mocha-style assertion syntax into Jasmine specs after skimming unrelated documentation.
Key Takeaways
karma-jasmine bridges Karma to Jasmine; jasmine-core provides the actual test syntax and matchers.
describe/it/beforeEach/expect form the foundation of nearly every Jasmine spec file.
Jasmine's built-in spyOn() covers most mocking needs without an external library.
Both async/await and the older done callback style are valid for asynchronous specs.
Pro Tip
When reading an unfamiliar legacy Karma suite, search for done( first. Seeing how much of the suite still uses the callback style versus async/await tells you a lot about how old the codebase's testing patterns are, and what modernization opportunities exist.
You now understand karma-jasmine in depth. Next, explore karma-mocha as the primary alternative framework adapter.