My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
MoxRecipes  
Some useful patterns for using Mox to test code.
Featured
Updated Jun 19, 2009 by dglasser

Introduction

Here we provide some common Mox recipes that people have found useful. This section's constantly under development; if you find a better way of implementing a recipe below, please let us know in the comments.

Set up your Mox test classes in a sane way

Note: many other recipes assume you've done this.

  def setUp(self):
    self.mox = mox.Mox()

  def tearDown(self):
    self.mox.UnsetStubs()

Stub out a method called from a constructor in the same class

TODO(damien): Write a public example here.

Stub out a static method in the class under test

  def testFoo(self):

    orig_method = module.class.StaticMethod

    static_stub = staticmethod(lambda *args, **kwargs: None)
    module.class.StaticMethod = static_stub

    self.mox.ReplayAll()

    ...

    self.mox.VerifyAll()

    module.class.StaticMethod = orig_method

Mock a module-level function in a different module

  def testFoo(self):

    self.mox.StubOutWithMock(module_to_mock, 'FunctionToMock')
    module_to_mock.FunctionToMock().AndReturn(foo)

    self.mox.ReplayAll()
    ...
    self.mox.VerifyAll()

Stub out a class in a different module

TODO(damien): Write a public example here.

Mock a method in the class under test.

TODO(damien): Investigate this further. Maybe stubbing out call would help?

  def testFoo(self):

    # Note the difference: we instantiate the class *before* Replaying.
    foo_instance = module_under_test.ClassUnderTest()
    self.mox.StubOutWithMock(foo_instance, 'MethodToStub')
    foo_instance.MethodToStub().AndReturn('foo')

    ...

    self.mox.ReplayAll()
    ...
    self.mox.VerifyAll()

Mock a generator in the class under test

  def testFoo(self):

    ...

    foo_instance = module_under_test.ClassUnderTest()
    self.mox.StubOutWithMock(foo_instance, 'GeneratorToStub')

    mygen = (x for x in [1, 2, 3])
    foo_instance.MethodToStub(mox.IsA(object)).AndReturn(mygen)

    ...

    self.mox.ReplayAll()

    ...

    self.mox.VerifyAll()

Mocking datetime.datetime.now

import datetime
import mox

m = mox.Mox()

# Stub out the datatime.datetime class.
m.StubOutWithMock(datetime, 'datetime')

# Record a call to 'now', and have it return the value '1234'
datetime.datetime.now().AndReturn(1234)

# Set the mocks to replay mode
m.ReplayAll()
  
# This will return '1234'
datetime.datetime.now()
  
# Verify the time was actually checked.
m.VerifyAll()

# Return datetime.datetime to its default (non-mock) state.
m.UnsetStubs()

Alternatively, rewrite your code so that you can mock out datetime.now without Mox:

def FunctionBeingTested(now=datetime.datetime.now):
  DoSomethingWith(now())

# in test code
def MyNow(): return 1234
FunctionBeingTested(now=MyNow)
Comment by trung%ph...@gtempaccount.com, Dec 31, 2009

is it possible to stub a constructor?

I couldn't do this: self.mox.StubOutWithMock?(ClassToMock?, 'init')

Comment by LeLu...@gmail.com, Feb 6, 2010

@tr.. hmm .. formatting probably removed your underscores in "__init__". I was able to do it with this same kind of call. I'm using pymox version 0.5.1. don't forget to record a call to it before putting your object in replay mode:

    mox_factory.StubOutWithMock(ClassType, "__init__")

    TomboyCommunicator.__init__().AndReturn( None )

    mox_factory.ReplayAll()

Here's a technique I am using to keep perfect control over what methods of an object get called or not during a test:

class TestSomething(unittest.TestCase):
    def setUp(self):
        self.m = mox.Mox()

    def tearDown(self):
        self.m.UnsetStubs()
        self.m.ResetAll()

    def wrap_subject(self, cls, subject_name):
        mock = self.m.CreateMock(cls)

        func = getattr(cls, subject_name)
        wrapper = lambda *x, **y: func(mock, *x, **y)
        setattr(mock, subject_name, wrapper)

        return mock

    def test_a_method_in_an_object(self):
        obj = self.wrap_subject(ObjectContainingMethod, "tested_method")

        # Record calls that should be made in tested_method

        self.m.ReplayAll()

        self.AssertEqual(
            "dummy result. change string to whatever needed",
            obj.tested_method()
        )

        self.m.VerifyAll()

I haven't found a clean way to do the same thing with functions in a module (not contained in an object). I guess I'll be encapsulating everything in classes to be able to test this way.

Code for this example was taken from my project over at GitHub

Comment by pengyu...@gmail.com, Mar 30, 2012

how to mox time.localtime().tm_sec?

Comment by pengyu...@gmail.com, Mar 31, 2012

my code:

.... t = time.gmtime(time.mktime((2012, 10, 1, 15, 26,0,0,0,0))) self.mox.StubOutWithMock?(time, 'localtime') time.localtime().AndReturn?(t) self.mox.ReplayAll?()
58 print "mox localtime:", time.localtime()
othermoudle.func() # call time.localtime() in func() ...
on the line 58,I got a correct mox time: (Pdb) time.localtime() time.struct_time(tm_year=2012, tm_mon=10, tm_mday=1, tm_hour=7, tm_min=26, tm_sec=0, tm_wday=0, tm_yday=275, tm_isdst=0)

and then call time.localtime in an other moudle, I got an error: (Pdb) time.time() 1333178201.334844 (Pdb) time.localtime() UnexpectedMethodCallError?: Unexpected method call Stub for <built-in function localtime>.call() -> None (Pdb)

Can u give me some tips why I got the error? thank u.


Sign in to add a comment
Powered by Google Project Hosting