Open nseniak-iziwork opened 3 years ago
ts-mockito
is using Proxy
for interfaces mocking. So when InversifyJS
wants to check if then
is a function:
function isPromise(object) {
var isObjectOrFunction = (typeof object === 'object' && object !== null) || typeof object === 'function';
return isObjectOrFunction && typeof object.then === "function";
}
ts-mockito
immediately creates mock function for then
- thats why InversifyJS
thinks its a mock. And ts-mockito
needs to do that because it cannot figure out if its a part of interface or not (interfaces are not available in runtime).
As a work around you can do when(mockedFoo['then']).thenReturn(undefined);
- but I think its ugly.
Faced this problem today. Currently resolved with tiny wrapper function based on @NagRock suggestion
function mockInterface<T>(): T {
const mocked = mock<T>();
when((mocked as any).then).thenReturn(undefined);
return mocked;
}
@NagRock Just encountered the same problem, but unfortunately I didn't see this post soon enough so had to spend a lot of time debugging. Since then
is so important for identifying a Promise
perhaps we should include it in the list of excludedFunctionNames
inside MockableFunctionsFinder
?
Yeah, also spend a long time to figure this issue out.
We use
inversify
for IOC (https://inversify.io/). Injecting mocks is an important testing use case for us. However, we found that interface mocks cannot be properly bound in inversify contexts.Here's code combining
inversify
andts-mockito
that shows the problem:After looking into the inversify code, it seems that the problem is that
inversify.isPromise
incorrectly returnstrue
for interface mocks, which makes invetsify try to resolve the mock, resulting in anull
value:The inversify code for
isPromise
is here: https://github.com/inversify/InversifyJS/blob/master/src/utils/async.ts