MockObject Suport For unittest.TestCase

Matt Russell matt at teaphoo.fsnet.co.uk
Thu Mar 20 09:18:17 EST 2003


Hi all,
I have recently been looking up on "how to contribute to python", and
think i may have jumped the gun a little....

already posted a patch to unittest.py on sf (and module) 
[ sf patch id: 706590 ], when If i was a little  more patient should
of announced my idea here first. *phew*

that out of the way --
I've been working with for present employers for about 4 years, doing
mainly python (and some java).  Now going to return (full time) to
univeristy and get cs degree. *yikes*

Anyhow, looking at the course syllabus, it's all java and C/C++ (which
I don't mind at all) - but would like to spread knowledge and promote
awareness of python (because i think it's the best thing since sliced
spam ;)
so i figure the best way to do this is to get involved with the
community.

'Been doing XP at my current job for a couple of years too..
 
we found that using mock objects can greatly improve unittests (If
used in
the correct context), especially for code that relis upon
hungry external resources.

--------
MockFactory 
---------
assumptions


notions
--------
* a MockFactory.__new__(Klass, [methods_to_override]) call (aliased as
createMockInstance in my proposed patch to unittest.py)
  will return a sudo instance of your real class.
  when testing in unittest.TestCase (for example)

from somemodule import MyDBO

  class BussinessApp:
    def __init__(self):
       self.db = MyDBO()
    def queryDb(self):
       #connect etc...
       # returns None or raises
    def main(self):
       someOtherCall()
       res=queryDb()
       if res:
         yac()
       # ..etc    


    class TestBusinessApp(unittest.TestCase):
        def testMain(self):
          myobj = BusinessApp()
          mockDBO = self.createMockInstance(MyDBO, ['connect',
'fetchall', 'cusror'])
          myobj.db = mockDBO
          myobj.db.someOtherMethod.setEventSequence([None])
          self.assertEqual(myobj.main(), someValue)
          
          # in another test u can do --
          myobj.db.connect.setEventSequence([DBError])
          self.assertRaises(DBError, myobj.main)

   
* each instance method of a mock object is a MockMethod object
  - a MockMethod object can be instructed what to do (raise/return
etc)
  - you can ask a mock method what arguments where passed *including
kwds*
  - when a mock method is called, it should be transparent (same as
calling the real method)

Most of the work I've done on this was inspired by the need for it at
work, the wy it came about was reading  XOP books and
xtreemeprogramming.com.

There is quite a lot already out there on Mock Objects,
but integrating mock objects with python's library, especially
unittest.py will (i hope) prevent less duplication.(we found we were
creaing mock subclasses of each object we wanted to mcok in previous
tests!! *lots of uneccessary code*)

It is no way as comprehensive as  java's (www.MockObject.com)
alternative, but because of python's dynamic nature, I don't think it
needs to be any more complicated.


I'm interested in contributing what i can to python (already read the
web site thoroughly) - any suggestions?


finally, thanks for reading - this is the first time I've ever
publically published any software i've created and i feel kinda weird
trying to sell it!!! :o

Matt Russell




More information about the Python-list mailing list