Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing with unittest.mock

Testing with unittest.mock

Ana Yankova

May 20, 2014
Tweet

More Decks by Ana Yankova

Other Decks in Programming

Transcript

  1. Testing
    with
    unittest.mock
    Ana Hristova

    View Slide


  2. Every tester has
    the heart of a
    developer

    View Slide

  3. Crowd Investment Platform
    CONNECTING INVESTORS AND ENTREPRENEURS
    THROUGH FUNDING
    [email protected]

    View Slide

  4. View Slide

  5. Sweden

    View Slide

  6. unittest.mock
    Testing library

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  10. How is this helpful?

    View Slide

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

    View Slide

  12. You are
    building a
    shiny new
    app …
    #
    $
    % %
    % %
    %
    &
    ' (
    )

    View Slide

  13. Please wait…
    … while your tests are running
    *

    View Slide

  14. Mock
    MagicMock
    patch( )

    View Slide

  15. Mock objects
    Callable

    View Slide

  16. Mock objects
    Create attributes on demand

    View Slide

  17. Mock objects
    Record how you use the
    attributes

    View Slide

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

    View Slide

  19. Examples

    View Slide

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

    View Slide

  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

    View Slide

  22. >>> mock = Mock()
    >>> mock

    >>> mock.method

    >>> mock.assetr_called_with(keyword=None)

    View Slide

  23. ...
    AttributeError: Mock object has no attribute
    'remove'
    >>> comment.remove
    >>> from unittest.mock import create_autospec
    >>>
    >>> comment = create_autospec(Comment)

    View Slide

  24. side effects

    View Slide

  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)

    View Slide

  26. magic methods
    Mocking

    View Slide

  27. >>> mock = Mock()
    >>> mock.__len__ = Mock()
    >>> mock.__len__.return_value = 42
    >>> len(mock)
    42
    !
    !

    View Slide

  28. MagicMock
    with default implementations
    of magic methods
    Subclass of Mock

    View Slide

  29. >>> mock = MagicMock()
    >>> int(mock)
    1
    >>> len(mock)
    0
    >>> list(mock)
    []
    >>> mock.__int__.called
    True

    View Slide

  30. patch( )
    Used to patch objects
    within the scope of the test

    View Slide

  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"

    View Slide

  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"

    View Slide

  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"

    View Slide

  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)

    View Slide

  35. Mock wisely!

    View Slide

  36. @anhristova
    +
    , anah

    View Slide