Pro Yearly is on sale from $80 to $50! »

Mock

Eb091ce308a085ec2ef5b6f10592cb62?s=47 Dan Langer
March 14, 2012

 Mock

Created for the Django Toronto meetup, a quick tour through the Python mock package.

Eb091ce308a085ec2ef5b6f10592cb62?s=128

Dan Langer

March 14, 2012
Tweet

Transcript

  1. mock==0.8.0

  2. Who am I? Dan Langer @dlanger daniel@langer.me daniel.langer.me

  3. None
  4. None
  5. >> import mock >> dir(mock) ['Mock', 'patch', ...]

  6. >> from mock import Mock

  7. Mocks all the way down >> k = Mock() >>

    k.foo.bar <Mock name="mock.foo.bar id=124> >> k.foo.bar() <Mock name="mock.foo.bar() id=128> >> k.foo.bar <Mock name="mock.foo.bar id=124> >> k.a.b.c.d.e.f.g.h.i.j.k.l.m <Mock name="..." id=1365>
  8. Configure your mocks >> from django.contrib.auth.models import User >> user1_mock

    = Mock() >> user1_mock.foo <Mock name=...> >> user2_mock = Mock(spec=User) >> user2_mock.foo AttributeError: ...
  9. Configure your mocks >> rmock = Mock(return_value=5) >> rmock(), rmock(4),

    rmock("W") (5, 5, 5) >> smock = Mock(side_effect=[1,2]) >> smock(), smock() (1, 2) >> emock = Mock(side_effect=Exception) >> emock() Exception: ...
  10. Inspect your mocks >> imock = Mock(return_value=None) >> imock() >>

    imock.call_count 1 >> imock(1, 2, 3, demo="ok") >> imock.call_args_list [call(1), call(1,2,3,demo='ok')]
  11. >> from mock import patch

  12. Daniel Coomber

  13. Patch all the things # utils.py def load_token(user) r =

    StrictRedis(host=...) [...] raw_token = r.rpop(token_id) return '--'.join([raw_token, ...]) # tests.py def test_load_token(self): redis_mock = Mock() redis_mock.return_value.rpop \ .return_value = 'TEST_TOKEN' with patch('utils.StrictRedis', redis_mock): load_token(self.test_user) self.assertEqual(...)
  14. Patch celery # tasks.py @task def process_chunk(chunk): pass @task def

    process_file(file): tasks = [] for ... st = process_chunk.subtask(chunk) tasks.append(st) process = TaskSet(tasks=tasks) process.apply_async()
  15. Patch celery # tests.py def test_process_file__two_subtasks(self): pc_mock = Mock() with

    patch('tasks.process_chunk', pc_mock): process_file.delay(...) self.assertEqual(pc_mock.call_count, 2) #Fails
  16. Patch celery # tests.py def test_process_file__two_subtasks(self): pc_mock = Mock() with

    patch('tasks.process_chunk.subtask', pc_mock): process_file.delay(...) self.assertEqual(pc_mock.call_count, 2)
  17. Patch built-ins # utils.py import message_defs def load_defaults(id) if getattr(message_defs,

    id, None): [...] # tests.py def test_load_defaults(self): with patch('__builtins__.getattr', return_value='Hi'): load_defaults('welcome') self.assertEqual(...)
  18. Patch built-ins # utils.py import message_defs def load_defaults(id) if getattr(message_defs,

    id, None): [...] # tests.py def test_load_defaults(self): with patch('utils.getattr', create=True, return_value='Hi'): load_defaults('welcome') self.assertEqual(...)
  19. Patch Django def test_template: mock_get_template = Mock( return_value=Template("Hi {{ username

    }}")) with patch('package.module.get_template', mock_get_template): [...] def test_verify_user(self): mock_get = Mock() mock_get.return_value = Mock(spec=User) with patch('utils.User.objects.get', mock_get): [...]
  20. Patch the ORM...sparingly # User.objects.filter(...).exclude(...) \ # .order_by(...) def test_user_filter(self):

    mock_filter = Mock() mock_filter.return_value.exclude \ .return_value.order_by.return_value = [...] with patch('utils.User.objects.filter', mock_filter): [...]
  21. Keep Reading @decorator syntax create_autospec MagicMock [...] http://www.voidspace.org. uk/python/mock/