Skip to content

Karma with Jasmine

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.

npm install --save-dev karma-jasmine jasmine-core

// karma.conf.js
config.set({
  frameworks: ['jasmine'],
  files: ['src/**/*.spec.js'],
  browsers: ['ChromeHeadless']
});

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.

describe('UserService', function() {
  it('calls the logger on save', function() {
    const logger = { log: function() {} };
    spyOn(logger, 'log');

    saveUser({ name: 'Ada' }, logger);

    expect(logger.log).toHaveBeenCalledWith('Saved: Ada');
  });
});

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.