The last few years I've created a library for mocking object in Typescript. A long time ago I wrote an article about it:
http://www.ilove-it.com/post/2016/07/28/mock-your-typescript-classes-and-interfaces-the-easy-way
A long time there was really one thing that I wanted to fix and that is mocking generic methods:
https://github.com/jjherscheid/ts-mocks/issues/9.
So what is the problem?
Typescript can determine the the return value for the mocks methods/properties. But with generic methods this will not work because there is no option to specify the type that will actually be used in the code. I will try to explain this using an example.
Let say you have a service with the following interface:
export interface SomeService {
get<T>(index: number): Observable<T>;
}
In your application you use the service to returns users:
someService.get<User>(10).subscribe((user) => /* do something with user */ );
If you would like to mock this in you unit test normally you would write:
mockSomeService
.setup(ss => ss.get)
.is((value) => of(someUser));
// or
mockSomeService
.extend({ get: (value) => of(someUser)});
Unfortunately typescript will complain about the fact that
of(someUser)
is not of type
Observable<T>
:
Type 'Observable<User>' is not assignable to type 'Observable<T>'.
Type 'User' is not assignable to type 'T'.
Now the as<T>()
comes into the rescue. With this method you can overrule the return value that is automatically determined by the setup() method.
Note: Please note that this can conflict with the real code if not used appropriately, so use at your own risc
mockSomeService
.setup(ss => ss.get)
.as<(number) => Observable<User>>()
.is((value) => of(someUser));
With this typescript will not complain anymore. Great! ;-)
So don't wait any longer and update your solution to ts-mocks 2.6.0