Skip to content

Instantly share code, notes, and snippets.

@mgrandrath
Created October 16, 2016 12:52
Show Gist options
  • Save mgrandrath/1a613ce154d24898ab333547b213a6dc to your computer and use it in GitHub Desktop.
Save mgrandrath/1a613ce154d24898ab333547b213a6dc to your computer and use it in GitHub Desktop.
const {keys, create, assign} = Object;
function fakeClass(Constructor, prototype) {
const methods = keys(Constructor.prototype);
const overrides = keys(prototype);
methods.forEach(function (method) {
if (!overrides.includes(method)) {
throw new Error(`Method "${method}" missing in Overrides for class [${Constructor.name}]`);
}
});
function FakeClass() {
Constructor.apply(this, arguments);
}
FakeClass.prototype = assign(create(Constructor.prototype), prototype);
return FakeClass;
}
// class to be faked
function SomeClass() {}
SomeClass.prototype.foo = function () {
console.log("foo");
};
SomeClass.prototype.bar = function () {
console.log("bar");
};
// this throws because method 'bar' is missing
const FailingFake = fakeClass(SomeClass, {
foo: function () {}
});
// create a fake class
const Fake = fakeClass(SomeClass, {
// override 'foo' with own behaviour
foo: function () {
this._fooCalled = true;
},
// re-use 'bar' as is
bar: SomeClass.prototype.bar,
// add additional methods
fooCalled() {
return this._fooCalled;
}
});
// create an instance
const someClassFake = new Fake();
someClassFake instanceof SomeClass; // => true
someClassFake instanceof Fake; // => true
someClassFake.bar(); // logs 'bar' to the console
someClassFake.foo(); // does not log to the console
someClassFake.fooCalled(); // => true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment