Source From Here
QuestionWhen you patch a function using mock, you have the option to specify autospec as True:
(http://www.voidspace.org.uk/python/mock/patch.html)
I'm wondering why this isn't the default behavior? Surely we would almost always want to catch passing incorrect parameters to any function we patch?
HowTo
The only clear way to explain this, is to actually quote the documentation on the downside of using auto-speccing and why you should be careful when using it:
I think the key takeaway here is to note this line: autospec can’t know about any dynamically created attributes and restricts the api to visible attributes
So, to help being more explicit with an example of where autospeccing breaks, this example taken from the documentation shows this:
- >>> class Something:
- ... def __init__(self):
- ... self.a = 33
- ...
- >>> with patch('__main__.Something', autospec=True):
- ... thing = Something()
- ... thing.a
- ...
- Traceback (most recent call last):
- ...
- AttributeError: Mock object has no attribute 'a'
Observe the below functional example:
- import unittest
- from mock import patch
- def some_external_thing():
- pass
- def something(x):
- return x
- class MyRealClass:
- def __init__(self):
- self.a = some_external_thing()
- def test_thing(self):
- return something(self.a)
- class MyTest(unittest.TestCase):
- def setUp(self):
- self.my_obj = MyRealClass()
- @patch('__main__.some_external_thing')
- @patch('__main__.something')
- def test_my_things(self, mock_something, mock_some_external_thing):
- mock_some_external_thing.return_value = "there be dragons"
- self.my_obj.a = mock_some_external_thing.return_value
- self.my_obj.test_thing()
- mock_something.assert_called_once_with("there be dragons")
- if __name__ == '__main__':
- unittest.main()