I need to patch current datetime in tests. I am using this solution:
def _utcnow():     return datetime.datetime.utcnow()   def utcnow():     """A proxy which can be patched in tests.     """     # another level of indirection, because some modules import utcnow     return _utcnow()   Then in my tests I do something like:
    with mock.patch('***.utils._utcnow', return_value=***):         ...   But today an idea came to me, that I could make the implementation simpler by patching __call__ of function utcnow instead of having an additional _utcnow.
This does not work for me:
    from ***.utils import utcnow     with mock.patch.object(utcnow, '__call__', return_value=***):         ...   How to do this elegantly?
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.
patch() uses this parameter to pass the mocked object into your test. From there, you can modify the mock or make assertions as necessary. You can execute this test module to ensure it's working as expected: $ python tests.py . -------------------------------------------------------
MagicMock. MagicMock objects provide a simple mocking interface that allows you to set the return value or other behavior of the function or object creation call that you patched. This allows you to fully define the behavior of the call and avoid creating real objects, which can be onerous.
When you patch __call__ of a function, you are setting the __call__ attribute of that instance. Python actually calls the __call__ method defined on the class.
For example:
>>> class A(object): ...     def __call__(self): ...         print 'a' ... >>> a = A() >>> a() a >>> def b(): print 'b' ... >>> b() b >>> a.__call__ = b >>> a() a >>> a.__call__ = b.__call__ >>> a() a   Assigning anything to a.__call__ is pointless.
However:
>>> A.__call__ = b.__call__ >>> a() b   a() does not call a.__call__. It calls type(a).__call__(a).
There is a good explanation of why that happens in answer to "Why type(x).__enter__(x) instead of x.__enter__() in Python standard contextlib?".
This behaviour is documented in Python documentation on Special method lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With