Skip to content

Karma with Mocha

Mocha is the primary alternative to Jasmine as a Karma framework adapter. This lesson covers setup, its BDD-style syntax, and why Mocha is almost always paired with a separate assertion library.

Setting Up karma-mocha

karma-mocha bridges Karma to Mocha, exposing Mocha's describe/it/before/after globals inside the browser. Unlike Jasmine, Mocha ships with no assertion library at all — you must add one separately, most commonly Chai (covered in the next lesson) or Node's built-in assert module.

npm install --save-dev karma-mocha mocha karma-chai chai

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

Both mocha (the test framework itself) and karma-mocha (the Karma adapter) must be installed together, plus an assertion library.

Mocha's BDD Interface

describe('Calculator', function() {
  let calc;

  beforeEach(function() {
    calc = new Calculator();
  });

  it('adds two numbers', function() {
    expect(calc.add(2, 3)).to.equal(5);
  });
});
  • Mocha's default interface (describe/it/beforeEach) looks nearly identical to Jasmine's on the surface.
  • The real difference is the assertion style: Chai's expect(x).to.equal(y) versus Jasmine's expect(x).toBe(y).
  • Mocha also supports a TDD-style interface (suite/test) via the ui client option, though BDD is far more common.
  • Mocha has no built-in mocking; teams commonly add Sinon alongside it for spies and stubs.

Mocha + Karma Cheat Sheet

Key packages and settings for a working Mocha-based Karma setup.

Need Package / Setting
Mocha test framework mocha
Karma adapter for Mocha karma-mocha
Assertions (BDD style) chai + karma-chai
Mocking/spies sinon (no Karma adapter needed; works as a plain script)
Per-test timeout client.mocha.timeout in karma.conf.js
TDD-style interface client.mocha.ui: 'tdd'

Mocha's Lifecycle Hooks

Mocha's before/after run once for an entire describe() block, while beforeEach/afterEach run around every individual it() — the same distinction Jasmine's beforeAll/beforeEach make, just with different names.

describe('Database connection', function() {
  before(function() {
    connectOnce();
  });

  after(function() {
    disconnectOnce();
  });

  beforeEach(function() {
    resetTestData();
  });

  it('reads a record', function() {
    expect(readRecord(1)).to.exist;
  });
});

Configuring Mocha Timeouts

Mocha fails any test that takes longer than its configured timeout (2000ms by default) without completing. For slower asynchronous specs, raise this globally through client.mocha.timeout rather than editing every test individually.

config.set({
  client: {
    mocha: {
      timeout: 5000
    }
  }
});

Individual specs can still override this with this.timeout(10000); inside a non-arrow function callback.

Common Mistakes

  • Installing karma-mocha without also installing mocha itself, or vice versa.
  • Forgetting an assertion library entirely and trying to use expect() with no library providing it.
  • Using arrow functions for spec callbacks that need this.timeout(), since arrow functions don't bind their own this.
  • Assuming Mocha and Jasmine matcher syntax are interchangeable when copying examples between the two.

Key Takeaways

  • karma-mocha bridges Karma to Mocha, but Mocha itself provides no assertions out of the box.
  • Mocha is almost always paired with Chai (or occasionally Sinon and Node's assert) for assertions.
  • Mocha's before/after and beforeEach/afterEach map directly onto Jasmine's beforeAll/beforeEach concepts.
  • Per-test timeouts are configurable globally via client.mocha.timeout or per-spec via this.timeout().

Pro Tip

If you're choosing Mocha specifically for its flexibility, decide on one assertion library (usually Chai) upfront and document it. Mixing assertion styles across a codebase makes specs harder to read for no real benefit.