---
description: How to use spies with Mocha for testing callbacks and function calls
title: Spies
---

Mocha does not come equipped with spies, though libraries like [Sinon](https://github.com/sinonjs/sinon) provide this behaviour if desired. The following is an example of Mocha utilizing Sinon to test an EventEmitter:

```javascript
import sinon from "sinon";
import { EventEmitter } from "node:events";

describe("EventEmitter", function () {
  describe("#emit()", function () {
    it("should invoke the callback", function () {
      const spy = sinon.spy(),
        emitter = new EventEmitter();

      emitter.on("foo", spy);
      emitter.emit("foo");
      sinon.assert.calledOnce(spy);
    });

    it("should pass arguments to the callbacks", function () {
      const spy = sinon.spy(),
        emitter = new EventEmitter();

      emitter.on("foo", spy);
      emitter.emit("foo", "bar", "baz");
      sinon.assert.calledOnce(spy);
      sinon.assert.calledWith(spy, "bar", "baz");
    });
  });
});
```

The following is the same test, performed without any special spy library, utilizing the Mocha `done([err])` callback as a means to assert that the callback has occurred, otherwise resulting in a timeout. Note that Mocha only allows `done()` to be invoked once, and will otherwise error.

```javascript
import { strict as assert } from "node:assert";
import { EventEmitter } from "node:events";

describe("EventEmitter", function () {
  describe("#emit()", function () {
    it("should invoke the callback", function (done) {
      const emitter = new EventEmitter();

      emitter.on("foo", done);
      emitter.emit("foo");
    });

    it("should pass arguments to the callbacks", function (done) {
      const emitter = new EventEmitter();

      emitter.on("foo", function (a, b) {
        assert.equal(a, "bar");
        assert.equal(b, "baz");
        done();
      });
      emitter.emit("foo", "bar", "baz");
    });
  });
});
```
