ts-mockito
ts-mockito copied to clipboard
Mocking abstract methods
Hello everyone. Working with the examples on version 2.3.0, I have created the following test:
abstract class Foo {
abstract getBar (num: number): string;
}
// Creating mock
let mockedFoo: Foo = mock(Foo)
// stub method before execution
when(mockedFoo.getBar(3)).thenReturn('three')
// Getting instance
let foo: Foo = instance(mockedFoo)
// prints three
console.log(foo.getBar(3))
// prints null, because "getBar(999)" was not stubbed
console.log(foo.getBar(999))
Expected output
three
null
Actual output
TypeError: mockedFoo.getBar is not a function
If I try to mock a concrete method on an abstract class however, the test works as expected.
Same problem for 2.3.1.
As a workaround one can create an abstract subclass with an empty implementation of the target method and use that subclass for mocking.
abstract class Foo {
abstract getBar (num: number): string;
}
abstract class DummyFoo {
getBar(num): any {};
}
// Creating mock
let mockedFoo: Foo = mock(DummyFoo)
Another workaround could be mock the abstract class and use the method as a getter.
abstract class Foo {
abstract getBar (num: number): string;
}
// Creating mock
let mockedFoo: Foo = mock(Foo)
// Using method as a get
when(mockedFoo.getBar)
.thenReturn(() => undefined); // or your desired value
Using the mock<Interface>() mechanism introduced in 2.4.0 for #117 , I no longer have this issue. I had previously been mocking a concrete implementation of my Abstract class but now I'm able to do something like:
export abstract class UserService {
abstract registerUser(user: User): Promise<RegisterUserResult>;
}
const mockedUserService: UserService = mock<UserService>();
when(mockedUserService.registerUser(anything())).thenResolve({userId: '1234'});
I'm pretty new in the TS world so I could very well be missing something important.