The Blog

Mar 2
3

Chai, the simple Python mock

by Aaron Westendorf

Categories

Here at Agora we take testing seriously, insisting that full test coverage always be part of a deliverable and adjusting our schedules accordingly. We are historically a Rails shop, but for a few years we have been developing an extensive Python code base and infrastructure to power our in-game offerings.

We’ve been using Mox as our mock testing solution since 2009, and though it has met all of our functional requirements, we’ve longed for the simplicity and power of Ruby’s Mocha framework. This past Friday we held our 3rd Hack-A-Thon, and Vitaly Babiy and I developed Chai, a mocking framework patterned after Mocha.

from chai import Chai

class CustomObject (object):
    def get(self, arg):
        pass

class TestCase(Chai):
    def test_mock_get(self):
        obj = CustomObject()
        expect(obj.get).args('name').returns('My Name')
        assert_equals(obj.get('name'), 'My Name')
        expect(obj.get).args('name').returns('Your Name')
        assert_equals(obj.get('name'), 'Your Name')

    def test_mock_get_with_at_most(self):
        obj = CustomObject()
        expect(obj.get).args('name').returns('My Name').at_most(2)
        assert_equals(obj.get('name'), 'My Name')
        assert_equals(obj.get('name'), 'My Name')
        assert_equals(obj.get('name'), 'My Name') # this one will fail

    def test_mock_object(self):
        mock = mock()
        expect(mock).args('name').returns('My Name')
        assert_equals('My Name', mock('name'))
        expect(mock.foo).args('name').returns('Your Name')
        assert_equals('Your Name', mock.foo('name'))

    def test_stub(self):
       obj = CustomObject()
       stub(obj.get)
       assert_equals(obj.get('name'), 'My Name') # this will fail

if __name__ == '__main__':
    import unittest2
    unittest2.main()

You can find the latest source and documentation at GitHub, or install from pypi. The current release is 0.1.0 and we’re looking for feedback. We’re adding lots of features and improving the API, so check back frequently.

  • Reddit
  • Digg
  • del.icio.us
  • Facebook
  • Tumblr
  • Twitter

Comments

  1. Yeah, I loved Mocha a lot so I wrote Fudge: http://farmdev.com/projects/fudge/

    I can see that yours stays more true to its API though. Also, I didn’t really like the invasive patching in Mocha so I left that out.

  2. This looks very promising!
    Wanted a Python mocking framework that’s as easy to use as Groovy’s GMock or ruby’s Mocha, I will definitely give this a try.
    (i don’t understand why so many Python mock frameworks are based on EasyMock, I would rather call it “anything but easy mock”)

Leave a Reply

*