ts-mockito icon indicating copy to clipboard operation
ts-mockito copied to clipboard

Deep mock

Open LucaRitz opened this issue 4 years ago • 11 comments

Hello there

I have googled a lot but didn't find any solution to create a deep stubbed mock described in the following example:

const route: ActivatedRoute = mock(ActivatedRoute); when(route.snapshot.queryParamMap.keys).thenReturn(['key']); // This does not work

The above code results in the following exception cause queryParamMap is undefined: TypeError: Cannot read property 'keys' of undefined

If I do something like this

const route: ActivatedRoute = mock(ActivatedRoute); const paramMap = mock<ParamMap>(); when(paramMap.keys).thenReturn([key]); when(route.snapshot.queryParamMap).thenReturn(instance(paramMap));

the following exception gets thrown: TypeError: Cannot read property 'methodStubCollection' of undefined

It seems that ts-mockito does not provide any deep mocks so I have to write const route: ActivatedRoute = mock(ActivatedRoute); const paramMap = mock<ParamMap>(); when(paramMap.keys).thenReturn([key]); const snapshot = mock(ActivatedRouteSnapshot); when(snapshot.queryParamMap).thenReturn(instance(paramMap)); when(route.snapshot).thenReturn(instance(snapshot));

to get what I expected with the one liner in the first example.

Is there any other workaround or didn't I google enough? ;) Thank you very much for your help.

LucaRitz avatar Dec 04 '19 07:12 LucaRitz

This would make the library incredibly more useful and easy to use. I think this is a must feature!

cesalberca avatar Dec 10 '19 10:12 cesalberca

I think it does not have to be the default case. In java-mockito, you have to declare that at the initialization of the mock, Type instance = mock(Type.class, RETURNS_DEEP_STUBS);

Something like this would be nice in ts-mockito: const route: ActivatedRoute = mock(ActivatedRoute, RETURNS_DEEP_STUBS);

LucaRitz avatar Dec 10 '19 14:12 LucaRitz

Strongly agree with this feature, which is default behavior for some other mocking library, such as ts-auto-mock, ts-mocks. Not sure why this doesn't attracts much attention from the author

jandk008 avatar Feb 07 '21 03:02 jandk008

Any solution?

ryacobi avatar Feb 23 '21 17:02 ryacobi

Any solution?

I use ts-auto-mock for mocking object with nested mocks when it's necessary.

jandk008 avatar Feb 24 '21 01:02 jandk008

Any solution?

I use ts-auto-mock for mocking object with nested mocks when it's necessary.

Are you able to use spies and conditional return values with ts-auto-mock? couldn't find it in their docs

ryacobi avatar Feb 24 '21 08:02 ryacobi

So, this was left behind...

any solution with ts-mockito to achieve this?

matgott avatar Jan 13 '22 15:01 matgott

Can we at least get an update on whether or not this is on the radar as a feature request or if it likely won't be implemented?

hheavener-kyd avatar Feb 08 '22 21:02 hheavener-kyd

There is a relatively pain-free pattern to manually nest mocks for chained function calls...

Given some class A

class A {
  getB(): B {return b}
}

and class B:

class B {
  getFoo(): string {return 'foo'}
}

Which would normally be used like so:

new A().getB().getFoo()

We can mock like

const mockA = mock<A>();
const mockB = mock<B>();
when(mockB.getFoo()).thenReturn("MOCKED VALUE MWAHA!")
when(mockA.getB()).thenReturn(mockB);

🎉

lancedolan avatar May 17 '22 22:05 lancedolan

Any solution?

I use ts-auto-mock for mocking object with nested mocks when it's necessary.

Are you able to use spies and conditional return values with ts-auto-mock? couldn't find it in their docs

Didn't try it. What I know is that the feature ts-auto-mock can provide is limited as well, so I have to use ts-auto-mock , ts-mocks and ts-mockito together, which is painful. hoping there is comprehensive version covering them all.

jandk008 avatar May 17 '22 23:05 jandk008

There is a relatively pain-free pattern to manually nest mocks for chained function calls...

Given some class A

class A {
  getB(): B {return b}
}

and class B:

class B {
  getFoo(): string {return 'foo'}
}

Which would normally be used like so:

new A().getB().getFoo()

We can mock like

const mockA = mock<A>();
const mockB = mock<B>();
when(mockB.getFoo()).thenReturn("MOCKED VALUE MWAHA!")
when(mockA.getB()).thenReturn(mockB);

🎉

It'll become much more complex when it is nested, checking the example posted by the OP.

jandk008 avatar May 17 '22 23:05 jandk008