Skip to content

Instantly share code, notes, and snippets.

@FelixRilling
Created March 24, 2019 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FelixRilling/7622b1b8da51c39faeb2304fc018003b to your computer and use it in GitHub Desktop.
Save FelixRilling/7622b1b8da51c39faeb2304fc018003b to your computer and use it in GitHub Desktop.
Basic mockito-style mocking and stubbing in JavaScript
const mockField = Symbol("mockField");
class Stub {
constructor(mockTarget, property, receiver, matchers = []) {
this.mockTarget = mockTarget;
this.property = property;
this.receiver = receiver;
this.matchers = matchers;
this.mocked = () => null;
}
matches(targetSecondary, propertySecondary, receiverSecondary) {
return propertySecondary === this.property;
}
getMocked(args) {
return this.mocked(args);
}
thenAnwser(answer) {
this.mocked = answer;
}
thenReturn(val) {
this.mocked = () => val;
}
thenThrow(throwable) {
this.mocked = () => throw throwable;
}
thenCallActual() {
this.mocked = (args) => this.mockTarget[this.property](args);
}
}
const when = (mockTarget) => new Proxy(mockTarget, {
get(mockTarget, property, receiver) {
const mockInstance = mockTarget[mockField];
if (!(property in mockInstance.actual)) {
throw new Error("Property does not exist in mock!");
}
return (...matchers) => {
const propMock = new Stub(mockTarget, property, receiver, matchers);
mockInstance.stubs.push(propMock);
return propMock;
};
}
});
const mock = (target) => {
const mockInstance = {
stubs: [],
actual: target
};
return new Proxy(target, {
get(target, property, receiver) {
if (property === mockField) {
return mockInstance;
}
for (let stub of mockInstance.stubs) {
// TODO add matcher checks
if (stub.matches(target, property, receiver)) {
return (...args) => stub.getMocked(args);
}
}
if (property in target) {
return () => null;
}
}
});
};
/**
* Example
*/
// Example class
class Foo {
getNumber() {
return 0;
}
}
const fooMock = mock(new Foo()); // Create plain mock.
when(fooMock).getNumber().thenReturn(100); // Mock getNumber() to return 100
console.log(fooMock.getNumber()); // Logs 100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment