Mock
Abstract
• Start to Write Test
• Start to Use Mock
• Tips
• You think quality is
important
the first thing
• pip install nose
• you will get a tool called nosetests
A very simple test
def add(left,right):
return left+right
!
def test_add():
assert add(4,5) == 9
Finding, Running, Report in
one shoot
nosetests sample.py
Ran 1 test in 0.001s
!
OK
if you meet problem
def add(left,right):
return left+right+1
!
def test_add():
assert add(4,5) == 9
!
trigger pdb as fail
nosetests sample_fail.py --pdb
assert add(4,5) == 9
(Pdb) p add(4,5)
10
(Pdb)
What nose do
• cooperate with doctest, unittest2
• add an additional function baed test case
• a test discover, test runner,
• plugin integration
unittest.TestCase
import unittest
!
def add(left,right):
return left+right
!
class addTestCase(unittest.TestCase):
def test_add(self):
self.assertEqual(5, add(5,5))
what else
• test fixture preparation
• setUP, tearDown
• setUp will be called before test method
• tearDown will be called after test method
what if
• if a function called erase_disk , how can I test
it?
• if a function will get a JSON from google, how
can I test it
Time to Introduce Mock
• python3.3 builtin
• pip install mock with python2.7
• it is a library
• it helps you to provide a fake object for spy
all-mighty
In : import mock
!
In : m = mock.Mock()
!
In : m.dock.dog.bark()
Out: <Mock
name='mock.dock.dog.bark()'
id='4320364368'>
obey your order
In: dog = mock.Mock(
return_value="bark")
!
In: dog()
Out: ‘bark’
!
In: dog.bark.return_value = u"WW"
!
In: dog.bark()
Out: u'WW'
!
mock tell you his story
In [9]: def reset_file(fs):
...: fs.seek(0)
...:!
In: m = mock.Mock()
!
In: reset_file(m)
!
In: m.seek.assert_called_with(0)
like python object
In : m = mock.MagicMock()
!
In : m['key']
Out: <MagicMock
name='mock.__getitem__()'
id=‘4311227728'>
!
In: m.__getitem__.return_value = 10
!
In: m[3]
Out: 10
magic mock assertion
In:
m.__getitem__.assert_called_with(3)
read spec
In : fake_str = mock.Mock(str)
!
In : fake_str.lower()
Out: <Mock name='mock.lower()'
id='4321150160'>
!
In : fake_str.LOWER
---------
AttributeError
General Usage
In : def count(fs):
...: return len(fs.read())
...:
In : fakefs = mock.Mock()
In : fakefs.read.return_value = "xx"
In : assert count(fakefs) == 2
Add Testability
• dependency should always pass from out side
• your design need to consider testability
Inversion of control
# not this
def to_be_test():
db = Database()
return db.all()
!
# write this
def to_be_test(db):
return db.all()
from mock import *
from StringIO import *
def do_print(): # hard to IoC
print "hi"
def test_print():
os = StringIO()
with patch('sys.stdout',
new=os):
do_print()
actual = os.getvalue()
expect = "hi"
assert expect in actual
Tips
• Q: How to maintain test case?
• refactor you test infrastructure often
• duplicated test code make you will feel tired
after interface changed
• Q: how much should I test?
• test the interface, not the implementation
• don’t test private method
• test public method
• Q: Test is slow, I don’t want to test
• write quick test
• mock time consuming object
• don’t execute time consuming test every time
• run failed test only while you meet error
Add test now
• My Project has no test …
• add test for new added code
• old code can add test latter
mock needs manage
• Mock is awesome, I want to mock every thing
• mock’s behavior may has error
• mock object tell you what you want to hear
• mock dependency is okay
• share mock among test modules
finding test utility
• Django mocks some service while testing
• GAE also provide mock while testing
• if you are using ORM, there a package that help
you mock ORM
After we have tests
• don’t forget to run test before you push codes
• nose can provide report
• nose can integration coverage report
Recap
• Nose is a good test driver
• unittest provide awesome test infrastructure
• any one want to share doctest?
• test and doc are combined !
• mock is used to fake a dependency, not every
thing

Mock Introduction

  • 1.
  • 2.
    Abstract • Start toWrite Test • Start to Use Mock • Tips
  • 3.
    • You thinkquality is important
  • 4.
    the first thing •pip install nose • you will get a tool called nosetests
  • 5.
    A very simpletest def add(left,right): return left+right ! def test_add(): assert add(4,5) == 9
  • 6.
    Finding, Running, Reportin one shoot nosetests sample.py Ran 1 test in 0.001s ! OK
  • 7.
    if you meetproblem def add(left,right): return left+right+1 ! def test_add(): assert add(4,5) == 9 !
  • 8.
    trigger pdb asfail nosetests sample_fail.py --pdb assert add(4,5) == 9 (Pdb) p add(4,5) 10 (Pdb)
  • 9.
    What nose do •cooperate with doctest, unittest2 • add an additional function baed test case • a test discover, test runner, • plugin integration
  • 10.
    unittest.TestCase import unittest ! def add(left,right): returnleft+right ! class addTestCase(unittest.TestCase): def test_add(self): self.assertEqual(5, add(5,5))
  • 11.
    what else • testfixture preparation • setUP, tearDown • setUp will be called before test method • tearDown will be called after test method
  • 12.
    what if • ifa function called erase_disk , how can I test it? • if a function will get a JSON from google, how can I test it
  • 13.
    Time to IntroduceMock • python3.3 builtin • pip install mock with python2.7 • it is a library • it helps you to provide a fake object for spy
  • 14.
    all-mighty In : importmock ! In : m = mock.Mock() ! In : m.dock.dog.bark() Out: <Mock name='mock.dock.dog.bark()' id='4320364368'>
  • 15.
    obey your order In:dog = mock.Mock( return_value="bark") ! In: dog() Out: ‘bark’ ! In: dog.bark.return_value = u"WW" ! In: dog.bark() Out: u'WW' !
  • 16.
    mock tell youhis story In [9]: def reset_file(fs): ...: fs.seek(0) ...:! In: m = mock.Mock() ! In: reset_file(m) ! In: m.seek.assert_called_with(0)
  • 17.
    like python object In: m = mock.MagicMock() ! In : m['key'] Out: <MagicMock name='mock.__getitem__()' id=‘4311227728'> ! In: m.__getitem__.return_value = 10 ! In: m[3] Out: 10
  • 18.
  • 19.
    read spec In :fake_str = mock.Mock(str) ! In : fake_str.lower() Out: <Mock name='mock.lower()' id='4321150160'> ! In : fake_str.LOWER --------- AttributeError
  • 20.
    General Usage In :def count(fs): ...: return len(fs.read()) ...: In : fakefs = mock.Mock() In : fakefs.read.return_value = "xx" In : assert count(fakefs) == 2
  • 21.
    Add Testability • dependencyshould always pass from out side • your design need to consider testability
  • 22.
    Inversion of control #not this def to_be_test(): db = Database() return db.all() ! # write this def to_be_test(db): return db.all()
  • 23.
    from mock import* from StringIO import * def do_print(): # hard to IoC print "hi" def test_print(): os = StringIO() with patch('sys.stdout', new=os): do_print() actual = os.getvalue() expect = "hi" assert expect in actual
  • 24.
    Tips • Q: Howto maintain test case? • refactor you test infrastructure often • duplicated test code make you will feel tired after interface changed
  • 25.
    • Q: howmuch should I test? • test the interface, not the implementation • don’t test private method • test public method
  • 26.
    • Q: Testis slow, I don’t want to test • write quick test • mock time consuming object • don’t execute time consuming test every time • run failed test only while you meet error
  • 27.
    Add test now •My Project has no test … • add test for new added code • old code can add test latter
  • 28.
    mock needs manage •Mock is awesome, I want to mock every thing • mock’s behavior may has error • mock object tell you what you want to hear • mock dependency is okay • share mock among test modules
  • 29.
    finding test utility •Django mocks some service while testing • GAE also provide mock while testing • if you are using ORM, there a package that help you mock ORM
  • 30.
    After we havetests • don’t forget to run test before you push codes • nose can provide report • nose can integration coverage report
  • 31.
    Recap • Nose isa good test driver • unittest provide awesome test infrastructure • any one want to share doctest? • test and doc are combined ! • mock is used to fake a dependency, not every thing