Closed shashankrnr32 closed 2 years ago
Yes, I wanted to do that at some point. I don't know a good name. For thenCallRealMethod
, I don't like the method in it as we're not restricted to methods in any way in Python. We generally work with callables. For example os.path.exists
is not a classical method.
For the implementation, look how RememberedProxyInvocation
does that for spy
: https://github.com/kaste/mockito-python/blob/27e5587ac683262aa883bcb48130ed1a974df517/mockito/invocation.py#L144-L151
Generally, I think when(rex).bark('Miau').thenReturn('Wuff').thenCallRealMethod().thenReturn('Puff')
is a very strange example. A bit more typical is for example to patch os.path.exists
where you often want the original implementation intact except for the very call in your unittest.
If I remember correctly, the way to do this right now is:
spy2(os.path.exists)
when(os.path).exists("/foo/bar").thenReturn(True)
which does the trick but is not very accessible for users. The idea behind thenCallOriginalImplementation
is to
make this work like so:
when(os.path).exists(...).thenCallOriginalImplementation()
when(os.path).exists("/foo/bar").thenReturn(True)
Here when(os.path).exists(...).thenCallOriginalImplementation()
is completely the same as and interchangeable with spy2(os.path.exists)
. T.i. we could reduce the API surface by deprecating spy2
and just relying on the one user endpoint when/2
.
Can you come up with some real examples? when(emailService).send().thenReturn(True).thenCallThrough().thenReturn(False)
doesn't sound correct.
Agreed that
when(rex).bark('Miau').thenReturn('Wuff').thenCallRealMethod().thenReturn('Puff')
may not be the best way of using it, but it could be done (For whatever reasons!)
One simple example I can think of is of a method making 2 API calls, one to an external endpoint and another to the localhost.
def my_method():
requests.get("https://unknownhost.com/path")
requests.get("https://localhost:4443/path")
For the above tested method, my expectation would be that the invocation return a stubbed value when the request is made to External endpoint while the call may be made to the server running locally. I know that this is not a "Ideal" usecase that this may be used, but something similar might be the usecase in different scenarios.
My test method would be
when(requests).get("https://unknownhost.com/path").thenReturn(mock())
when(requests).get(...).thenCallOriginalImpl()
I will add more examples if I think of anymore!
This has been implemented by @avandierast and released.
Note: Please feel free to close the issue if this has been discussed before in any of the issue.
Currently the
AnswerSelector
interface provides the following methods to be used withwhen
orwhen2
statementthenReturn
: To return a mocked return valuethenRaise
: To raise a mock exceptionthenAnswer
: To call a custom method (Eg: Lambdas)I noticed the original method is stored in the
__wrapped__
attribute when the method is stubbed.https://github.com/kaste/mockito-python/blob/8e1771c5bb1c3bc5948c167c81768d2380c11c3b/mockito/mocking.py#L122
This issue is to provide another option
thenCallRealMethod
to AnswerSelector to call this original method instead of mocking a stub value so that the original method get called instead of the mock. This will support "Partial Mocking" of these methods by allowing the user to call the original method in case the original method is not modifiable.I have a small work here to support this (untested for now)
(I don't need this as such for my usecase, just some improvement!.)
Example:
Also see: https://javadoc.io/static/org.mockito/mockito-core/4.1.0/org/mockito/stubbing/OngoingStubbing.html#thenCallRealMethod--
Thank you.