Testing with unittest.mock

Testing with unittest.mock

D695739e92e74c0f35e5e2e4f270a1d7?s=128

Ana Yankova

May 20, 2014
Tweet

Transcript

  1. Testing with unittest.mock Ana Hristova

  2. ♥ Every tester has the heart of a developer

  3. Crowd Investment Platform CONNECTING INVESTORS AND ENTREPRENEURS THROUGH FUNDING ana@fundedbyme.com

  4. None
  5. Sweden

  6. unittest.mock Testing library

  7. Part of the Python Standard Library as of Python 3.3

    unittest.mock
  8. For older versions: unittest.mock $ pip install mock

  9. unittest.mock helps you create mock objects and make assertions about

    them
  10. How is this helpful?

  11. You want to test code that depends on the "

    date or time
  12. You are building a shiny new app … # $

    % % % % % & ' ( )
  13. Please wait… … while your tests are running *

  14. Mock MagicMock patch( )

  15. Mock objects Callable

  16. Mock objects Create attributes on demand

  17. Mock objects Record how you use the attributes

  18. Allow you to set return values or limit the available

    attributes Mock objects
  19. Examples

  20. >>> class Comment: ... ... def create(self, text, parent=None): ...

    pass ... comment = Comment()
  21. >>> comment.create = Mock(return_value=True) >>> comment.create(text=‘hello') True >>> comment.create. \

    ... assert_called_once_with(text=‘hello’) >>> comment.create.called True >>> comment.create.call_args call(text='hello') >>> comment.call_count 1
  22. >>> mock = Mock() >>> mock <Mock id='4353021072'> >>> mock.method

    <Mock name='mock.method' id=‘4352854800'> >>> mock.assetr_called_with(keyword=None)
  23. ... AttributeError: Mock object has no attribute 'remove' >>> comment.remove

    >>> from unittest.mock import create_autospec >>> >>> comment = create_autospec(Comment)
  24. side effects

  25. >>> comment.create.side_effect = \ ... ConnectionError(“Connection refused”) >>> ... ConnectionError:

    Connection refused >>> comment.create.mock_calls [call(parent=None, text='Hello')] >>> >>> comment.create(text="Hello", parent=None)
  26. magic methods Mocking

  27. >>> mock = Mock() >>> mock.__len__ = Mock() >>> mock.__len__.return_value

    = 42 >>> len(mock) 42 ! !
  28. MagicMock with default implementations of magic methods Subclass of Mock

  29. >>> mock = MagicMock() >>> int(mock) 1 >>> len(mock) 0

    >>> list(mock) [] >>> mock.__int__.called True
  30. patch( ) Used to patch objects within the scope of

    the test
  31. #event.py from datetime import date ! class Event(): ! def

    get_state(self): if self.end_date < date.today(): return "PAST" if self.start_date > date.today(): return "FUTURE" if self.start_date <= date.today() <= self.end_date: return "CURRENT"
  32. #test.py from datetime import date ! class EventTests(TestCase): def setUp(self):

    self.pycon = Event() self.pycon.start_date = date(2014, 5, 20) self.pycon.end_date = date(2014, 5, 21) ! @patch('event.date') def test_event_has_passed(self, mock_date): mock_date.today.return_value = date(2014, 5, 22) assert self.pycon.get_state() == "PAST"
  33. @patch('event.date') def test_event_has_passed(self, mock_date): mock_date.today.return_value = date(2014, 5, 22) assert

    self.pycon.get_state() == "PAST"
  34. class UserProfileSaveTests(TestCase): ! def setUp(self): self.profile = UserProfileFactory.build(user=UserFactory()) ! !

    @patch("notifications.tasks.subscribe_to_newsletter.delay") def test_subscribe_to_newsletter(self, subscribe_mock): self.profile.newsletter = True self.profile.save() subscribe_mock.assert_called_once_with(self.profile.user)
  35. Mock wisely!

  36. @anhristova + , anah