Python mock patch argument `new` vs `new_callable`
Question:
From the documentation http://www.voidspace.org.uk/python/mock/patch.html
patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
If new is omitted, then the target is replaced with a MagicMock. If patch is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function. If patch is used as a context manager the created mock is returned by the context manager.
new_callable allows you to specify a different class, or callable
object, that will be called to create the new object. By default
MagicMock is used.
I am trying to understand the differences between the two, and what situation to use new_callable
instead of new
Answers:
[EDIT]
In that answer I missed the most important thing that new
take an object and new_callable
a callable (the factory) as said correctly by @chepner. I don’t remove it because it contains either some useful notes.
By digging the code https://code.google.com/p/mock/source/browse/mock.py#1266 is clear that by new
you cannot set the attributes by nominal arguments and use spec
or spec_set
because it will raise a TypeError
exception.
new_callable
can be a subclass of NonCallableMock
itself and you can use all mock facilities in patch definition.
Sure that behavior is really not documented and also in http://www.voidspace.org.uk/python/mock/changelog.html#version-0-8-0 you can’t find much more than.
New new_callable argument to patch and patch.object allowing you to
pass in a class or callable object (instead of MagicMock) that will be
called to replace the object being patched
Anyway you cannot use something like that to create a YourMockSubclass
that have the myobject
signature
@patch("mymodule.myobject", new=YourMockSubclass(), spec=myobject)
but in that case you must use new_callable
:
@patch("mymodule.myobject", new_callable=YourMockSubclass, spec=myobject)
So you have to use new_callable
every time you need a non-MagicMock mock for your mock.
IMHO the only useful use is mocking property.
new
is an actual object; new_callable
is a callable used to create an object. The two cannot be used together (you either specify the replacement or a function to create the replacement; it’s an error to use both.)
>>> foo = 6
>>> with mock.patch('__main__.foo', new=7):
... print foo
...
7
>>> with mock.patch('__main__.foo', new_callable=lambda : 8):
... print foo
...
8
When new
is mock.DEFAULT
, the mock object is a MagicMock
instance precisely because the default value of new_callable
is MagicMock
.
From the documentation http://www.voidspace.org.uk/python/mock/patch.html
patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)
If new is omitted, then the target is replaced with a MagicMock. If patch is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function. If patch is used as a context manager the created mock is returned by the context manager.
new_callable allows you to specify a different class, or callable
object, that will be called to create the new object. By default
MagicMock is used.
I am trying to understand the differences between the two, and what situation to use new_callable
instead of new
[EDIT]
In that answer I missed the most important thing that new
take an object and new_callable
a callable (the factory) as said correctly by @chepner. I don’t remove it because it contains either some useful notes.
By digging the code https://code.google.com/p/mock/source/browse/mock.py#1266 is clear that by new
you cannot set the attributes by nominal arguments and use spec
or spec_set
because it will raise a TypeError
exception.
new_callable
can be a subclass of NonCallableMock
itself and you can use all mock facilities in patch definition.
Sure that behavior is really not documented and also in http://www.voidspace.org.uk/python/mock/changelog.html#version-0-8-0 you can’t find much more than.
New new_callable argument to patch and patch.object allowing you to
pass in a class or callable object (instead of MagicMock) that will be
called to replace the object being patched
Anyway you cannot use something like that to create a YourMockSubclass
that have the myobject
signature
@patch("mymodule.myobject", new=YourMockSubclass(), spec=myobject)
but in that case you must use new_callable
:
@patch("mymodule.myobject", new_callable=YourMockSubclass, spec=myobject)
So you have to use new_callable
every time you need a non-MagicMock mock for your mock.
IMHO the only useful use is mocking property.
new
is an actual object; new_callable
is a callable used to create an object. The two cannot be used together (you either specify the replacement or a function to create the replacement; it’s an error to use both.)
>>> foo = 6
>>> with mock.patch('__main__.foo', new=7):
... print foo
...
7
>>> with mock.patch('__main__.foo', new_callable=lambda : 8):
... print foo
...
8
When new
is mock.DEFAULT
, the mock object is a MagicMock
instance precisely because the default value of new_callable
is MagicMock
.