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

Mock

Avatar for Dan Langer Dan Langer
March 14, 2012

 Mock

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

Avatar for Dan Langer

Dan Langer

March 14, 2012
Tweet

More Decks by Dan Langer

Other Decks in Technology

Transcript

  1. 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>
  2. 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: ...
  3. 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: ...
  4. 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')]
  5. 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(...)
  6. 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()
  7. 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
  8. 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)
  9. 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(...)
  10. 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(...)
  11. 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): [...]
  12. 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): [...]