|
MoxRecipes
Some useful patterns for using Mox to test code.
Featured IntroductionHere 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 wayNote: 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 classTODO(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_methodMock 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 moduleTODO(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.nowimport 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) |
► Sign in to add a comment
is it possible to stub a constructor?
I couldn't do this: self.mox.StubOutWithMock?(ClassToMock?, 'init')
@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
how to mox time.localtime().tm_sec?
my code:
58 print "mox localtime:", time.localtime() 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.