Skip to content

Commit 30c2ee8

Browse files
Adding support for mocking interfaces
1 parent 5537d50 commit 30c2ee8

File tree

4 files changed

+68
-6
lines changed

4 files changed

+68
-6
lines changed

src/Mock.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export class Mocker {
1818
private mockableFunctionsFinder = new MockableFunctionsFinder();
1919
private objectPropertyCodeRetriever = new ObjectPropertyCodeRetriever();
2020

21-
constructor(private clazz: any, protected instance: any = {}) {
21+
constructor(private clazz: any, intf: boolean, protected instance: any = {}) {
22+
this.mock.__tsmockitoInterface = intf;
2223
this.mock.__tsmockitoInstance = this.instance;
2324
this.mock.__tsmockitoMocker = this;
2425
if (_.isObject(this.clazz) && _.isObject(this.instance)) {
@@ -40,8 +41,13 @@ export class Mocker {
4041
get: (target: any, name: PropertyKey) => {
4142
const hasMethodStub = name in target;
4243
if (!hasMethodStub) {
43-
this.createPropertyStub(name.toString());
44-
this.createInstancePropertyDescriptorListener(name.toString(), {}, this.clazz.prototype);
44+
if (this.mock.__tsmockitoInterface) {
45+
this.createMethodStub(name.toString());
46+
this.createInstanceActionListener(name.toString(), {});
47+
} else {
48+
this.createPropertyStub(name.toString());
49+
this.createInstancePropertyDescriptorListener(name.toString(), {}, this.clazz.prototype);
50+
}
4551
}
4652
return target[name];
4753
},

src/Spy.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class Spy extends Mocker {
88
private realMethods: { [key: string]: RealMethod };
99

1010
constructor(instance: any) {
11-
super(instance.constructor, instance);
11+
super(instance.constructor, false, instance);
1212

1313
if (_.isObject(instance)) {
1414
this.processProperties(instance);

src/ts-mockito.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,18 @@ export function spy<T>(instanceToSpy: T): T {
3232
}
3333

3434
export function mock<T>(clazz: { new(...args: any[]): T; } | (Function & { prototype: T }) ): T {
35-
return new Mocker(clazz).getMock();
35+
return new Mocker(clazz, false).getMock();
36+
}
37+
38+
export function imock<T>(): T {
39+
class Empty {}
40+
const mockedValue = new Mocker(Empty, true).getMock();
41+
42+
if (typeof Proxy === "undefined") {
43+
return mockedValue;
44+
}
45+
const tsmockitoMocker = mockedValue.__tsmockitoMocker;
46+
return new Proxy(mockedValue, tsmockitoMocker.createCatchAllHandlerForRemainingPropertiesWithoutGetters());
3647
}
3748

3849
export function verify<T>(method: T): MethodStubVerificator<T> {

test/mocking.types.spec.ts

+46-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {MethodToStub} from "../src/MethodToStub";
2-
import {instance, mock, when} from "../src/ts-mockito";
2+
import {imock, instance, mock, verify, when} from "../src/ts-mockito";
33
import {Bar} from "./utils/Bar";
44

55
describe("mocking", () => {
@@ -152,6 +152,51 @@ describe("mocking", () => {
152152

153153
});
154154
});
155+
156+
describe("mocking an interface", () => {
157+
let mockedFoo: SampleInterface;
158+
let foo: SampleInterface;
159+
160+
it("can create interface mock", () => {
161+
// given
162+
163+
// when
164+
mockedFoo = imock();
165+
foo = instance(mockedFoo);
166+
167+
// then
168+
});
169+
170+
if (typeof Proxy !== "undefined") {
171+
172+
it("can verify call count", () => {
173+
// given
174+
mockedFoo = imock();
175+
foo = instance(mockedFoo);
176+
177+
// when
178+
const result = foo.sampleMethod();
179+
180+
// then
181+
verify(mockedFoo.sampleMethod()).called();
182+
expect(result).toBe(null);
183+
});
184+
185+
it("can setup call actions", () => {
186+
// given
187+
mockedFoo = imock();
188+
foo = instance(mockedFoo);
189+
when(mockedFoo.sampleMethod()).thenReturn(5);
190+
191+
// when
192+
const result = foo.sampleMethod();
193+
194+
// then
195+
verify(mockedFoo.sampleMethod()).called();
196+
expect(result).toBe(5);
197+
});
198+
}
199+
});
155200
});
156201

157202
abstract class SampleAbstractClass {

0 commit comments

Comments
 (0)