Reputation: 408
I haven't been able to found a good explanation of this in the net, I'm guessing that i'm missing something trivial but I haven't been able to find it, so I came here to ask the experts :)
I have a test were I need to patch a constructor call, reading the docs as I understand, something like this should work, but:
import unittest.mock as mocker
import some_module
mock_class1 = mocker.patch('some_module.some_class')
print(mock_class1 is some_module.some_class) # Returns False
print(mock_class1) # <unittest.mock._patch>
mock_instance1 = mock_class1.return_value # _patch object has no attr return_value
Instead I get a different output if I do this
with mocker.patch('some_module.some_class') as mock_class2:
print(mock_class2 is some_module.some_class) # Returns True
print(mock_class2) # <MagicMock name=...>
mock_instance2 = mock_class2.return_value # No problem
print(mock_instance2) # <NonCallableMagicMock name=...>
Now, for the test itself, i'm using pytest-mock module which gives a mocker fixture that behaves like the first code block.
I would like to know:
why the behavior differs depending on the way that one call the mock framework
is there a clean way to trigger the behavior of the second code block without the with
clause?
Upvotes: 0
Views: 364
Reputation: 3765
1) pytest mocker plugin is being developer to avoid use of context managers; and probably not everybody fond of the way the standard mock plays with functions parameter 2) not really. It is intended to be used either as content manager or function decorator. I think it is possible use mocker package without pytest
References https://github.com/pytest-dev/pytest-mock https://www.packtpub.com/mapt/book/application_development/9781847198846/5/ch05lvl1sec45/integrating-with-python-mocker
What about installing pytest-mock and creating a test like this
import itertools
def test1(mocker):
mock_class1 = mocker.patch('itertools.count')
print(mock_class1 is itertools.count)
print(mock_class1)
mock_instance1 = mock_class1.return_value # Magic staff...
or may be using monkeypatching? Just do not use the standard unittest.mock with pytest
Upvotes: 2