Create a Jasmine Spy Object That’s Also An EventEmitter
Say you’re writing Jasmine tests for Node.js to test some module FooModule
. FooModule
expects to have an instance of some non-trivial service BarService
injected into its constructor so it can call lots of methods on it. One easy way to create a mock of BarService
’s complicated interface without creating a real object and stubbing out all of its many methods is to use jasmine.createSpyObj()
:
var mockBarService = jasmine.createSpyObj("BarService", [
"reload",
"hasChanges",
"addLink",
"replaceLink",
"deleteLink",
"hasLinkForUrl",
"setApiKey",
"setSessionManager",
// ...
]);
var moduleToTest = new FooModule(mockBarService);
But what if FooModule
also expects to register for events on its instance of BarService
, because the real BarService
inherits from EventEmitter
?
For the real BarService
, we have access to its constructor function, so we can use Util.inherits(BarService, EventEmitter)
. But here in this unit test, jasmine.createSpyObj()
creates the mock instance from {}
, meaning the mock instance’s constructor function is Object
. And trying to make Object
inherit from EventEmitter
seemed like a bad idea.
After several dumb attempts at making this work - which I’ll spare you from - I found the answer. I’m recording it here so I don’t forget, and because I didn’t find an acceptable answer anywhere else:
var mockBarService = jasmine.createSpyObj("BarService", [
//...
]);
_.assign(mockBarService, EventEmitter.prototype);
var moduleToTest = new FooModule(mockBarService);
This uses Lodash’s _.assign()
to assign the necessary properties of EventEmitter
’s prototype to the mock instance. I suppose the same thing could be done with ECMAScript 6’s Object.assign()
if that’s available to you.