Skip to content

Commit

Permalink
Adding support for mocking interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
johanblumenberg committed Jan 5, 2018
1 parent 5537d50 commit b9a7bb7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
14 changes: 10 additions & 4 deletions src/Mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export class Mocker {
private mockableFunctionsFinder = new MockableFunctionsFinder();
private objectPropertyCodeRetriever = new ObjectPropertyCodeRetriever();

constructor(private clazz: any, protected instance: any = {}) {
constructor(private clazz: any, intf: boolean, protected instance: any = {}) {
this.mock.__tsmockitoInterface = intf;
this.mock.__tsmockitoInstance = this.instance;
this.mock.__tsmockitoMocker = this;
if (_.isObject(this.clazz) && _.isObject(this.instance)) {
Expand All @@ -40,11 +41,16 @@ export class Mocker {
get: (target: any, name: PropertyKey) => {
const hasMethodStub = name in target;
if (!hasMethodStub) {
this.createPropertyStub(name.toString());
this.createInstancePropertyDescriptorListener(name.toString(), {}, this.clazz.prototype);
if (this.mock.__tsmockitoInterface) {
this.createMethodStub(name.toString());
this.createInstanceActionListener(name.toString(), {});
} else {
this.createPropertyStub(name.toString());
this.createInstancePropertyDescriptorListener(name.toString(), {}, this.clazz.prototype);
}
}
return target[name];
},
}
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/Spy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class Spy extends Mocker {
private realMethods: { [key: string]: RealMethod };

constructor(instance: any) {
super(instance.constructor, instance);
super(instance.constructor, false, instance);

if (_.isObject(instance)) {
this.processProperties(instance);
Expand Down
13 changes: 12 additions & 1 deletion src/ts-mockito.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,18 @@ export function spy<T>(instanceToSpy: T): T {
}

export function mock<T>(clazz: { new(...args: any[]): T; } | (Function & { prototype: T }) ): T {
return new Mocker(clazz).getMock();
return new Mocker(clazz, false).getMock();
}

export function imock<T>(): T {
class Empty {}
let mockedValue = new Mocker(Empty, true).getMock();

if (typeof Proxy === "undefined") {
return mockedValue;
}
var tsmockitoMocker = mockedValue.__tsmockitoMocker;
return new Proxy(mockedValue, tsmockitoMocker.createCatchAllHandlerForRemainingPropertiesWithoutGetters());
}

export function verify<T>(method: T): MethodStubVerificator<T> {
Expand Down
37 changes: 36 additions & 1 deletion test/mocking.types.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MethodToStub} from "../src/MethodToStub";
import {instance, mock, when} from "../src/ts-mockito";
import {instance, mock, imock, when, verify} from "../src/ts-mockito";
import {Bar} from "./utils/Bar";

describe("mocking", () => {
Expand Down Expand Up @@ -152,6 +152,41 @@ describe("mocking", () => {

});
});

describe("mocking an interface", () => {
let mockedFoo: SampleInterface;
let foo: SampleInterface;

if (typeof Proxy !== "undefined") {

it("can verify call count", () => {
// given
mockedFoo = imock();
foo = instance(mockedFoo);

// when
let result = foo.sampleMethod();

// then
verify(mockedFoo.sampleMethod()).called();
expect(result).toBe(null);
});

it("can setup call actions", () => {
// given
mockedFoo = imock();
foo = instance(mockedFoo);
when(mockedFoo.sampleMethod()).thenReturn(5);

// when
let result = foo.sampleMethod();

// then
verify(mockedFoo.sampleMethod()).called();
expect(result).toBe(5);
});
}
});
});

abstract class SampleAbstractClass {
Expand Down

0 comments on commit b9a7bb7

Please sign in to comment.