unit testing with mocks

25
Unit Testing with Mocks nasi http://twitter.com/nasiless

Upload: nathan-li

Post on 25-May-2015

2.081 views

Category:

Technology


3 download

DESCRIPTION

June 13th, 2009 - CPyUG (China Python User Group)

TRANSCRIPT

Page 1: Unit Testing with Mocks

Unit Testing with Mocksnasi

http://twitter.com/nasiless

Page 2: Unit Testing with Mocks

Introducing Myself

Architect

Editor

Translator

Page 3: Unit Testing with Mocks

Unit Testing

Page 4: Unit Testing with Mocks

A World ...without Unit Testing

Page 5: Unit Testing with Mocks

Verify

Design

Document

Regression

Page 6: Unit Testing with Mocks

Edit & Pray

Page 7: Unit Testing with Mocks

Cover & Modify

Page 8: Unit Testing with Mocks

Python: unittest Moduleimport unittest

class MyTestCase(unittest.TestCase): def test1(self): """Run test 1""" pass

def test2(self): """Run test 2""" pass

if __name__ == '__main__': unittest.main()

Page 9: Unit Testing with Mocks

Common unittest Methods

• assertTrue / assertFalse

• assertEquals

• assertRaises

• etc. • setUp

• tearDown

Page 10: Unit Testing with Mocks
Page 11: Unit Testing with Mocks

A test is not a unit test if:

• It talks to a database.

• It communicates across a network.

• It touches the file system.

-- Working Effectively with Legacy Code

Page 12: Unit Testing with Mocks

how ?!

Page 13: Unit Testing with Mocks

You need mock objects

• pMock (based on jMock)http://pmock.sourceforge.net/

• pyMock (based on EasyMock)http://theblobshop.com/pymock/

• minimock / mock / mox / mocker / ...

Mock Frameworks in Python:

Page 14: Unit Testing with Mocks

Introducing fudge

• Domain Specific Language

• Powerful Patcher Built-in

• Expect something, Verify it

• Still Alive

http://farmdev.com/projects/fudge

Page 15: Unit Testing with Mocks

common coding style for testing with mock objects

Page 16: Unit Testing with Mocks

(1) Create instances of mock objectsmock = fudge.Fake('mock')

(2) Set state and expectations in the mock objectsmock.expects('method') \ .with_args(arg1=1, arg2='2').returns(True)

(3) Invoke domain code with mock objects as parametersmock.method(arg1=1, arg2='2')

(4) Verify consistency in the mock objectsfudge.verify()

Page 17: Unit Testing with Mocks

Examples

Page 18: Unit Testing with Mocks

Testing Databaseimport MySQLdb

def Foo(): conn = MySQLdb.connect(host='localhost', user='root', db='test') cursor = conn.cursor()

cursor.execute('SELECT * FROM people') id, name = cursor.fetchone() print id, name

if __name__ == '__main__': Foo()

Page 19: Unit Testing with Mocks

Mock Databaseimport fudgefrom testmod import Foo

mysqldb = fudge.Fake('MySQLdb')

conn = mysqldb.expects('connect').returns_fake()curs = conn.provides('cursor').returns_fake()curs = curs.expects('execute').returns(1)curs = curs.provides('fetchone').returns((1, 'Nathan'))

@[email protected]_patched_object('testmod', 'MySQLdb', mysqldb)def Test(): Foo() # prints: 1 Nathan

if __name__ == '__main__': Test()

Page 20: Unit Testing with Mocks

Testing Network

import urllib2

def Foo(): print urllib2.urlopen('http://www.google.com/').read()

if __name__ == '__main__': Foo()

Page 21: Unit Testing with Mocks

Mock Networkimport fudgefrom cStringIO import StringIOfrom testmod import Foo

urlopen = fudge.Fake('urlopen', callable=True) \ .returns(StringIO('HelloWorld'))

@[email protected]_patched_object('urllib2', 'urlopen', urlopen)def Test(): Foo() # prints: HelloWorld

if __name__ == '__main__': Test()

Page 22: Unit Testing with Mocks

Testing File System

import os

def Foo(): print os.listdir('.') open('a.txt', 'w').write('HelloWorld')

if __name__ == '__main__': Foo()

Page 23: Unit Testing with Mocks

Mock File Systemimport fudgefrom cStringIO import StringIOfrom testmod import Foo

listdir = fudge.Fake(callable=True).returns(['a.txt', 'b.jpg'])buf = StringIO()myopen = lambda filename, mode: buf

@[email protected]_patched_object('os', 'listdir', listdir)@fudge.with_patched_object('__builtin__', 'open', myopen)def Test(): Foo() # prints: ['a.txt', 'b.jpg'] print buf.getvalue() # prints: HelloWorld

if __name__ == '__main__': Test()

Page 24: Unit Testing with Mocks

Pros and Cons

Page 25: Unit Testing with Mocks

Q & A