pythonunit-testingmockingpymox

Pros and Cons of CreateMockAnything() of Mox (pymox) framework


First of all the reason for the question - official pymox documentation: https://code.google.com/p/pymox/wiki/MoxDocumentation

There is a statement in MockAnything section telling "Don't use this unless you absolutely have to!". I'm interesting why is that? Does it have some limitations? Personally I found it very useful.

I have the following situation: I have a reference to the module in my class, the module have a bunch of module-level functions used by my class.

import db

class A(object):
    def __init__(self):
        # To make possible dependency injection.
        self.db = db
    ...

class Test_A(object):
    def test(self):
        a = A()
        # Perform an injection.
        a.db = mox.CreateMockAnything()
        # Setting an expectation to any function
        a.db.some_func().AndReturn(5)
        ...

Since this is a module I can't mock it with CreateMock() because this is not a type. Therefore I used CreateMockAnything() which is perfect for this case. I know I can stub module functions with:

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

But I don't like this way because here I need to do two actions each time. It's simpler and prettier to have a reference to the module in the class, and mock it with CreateMockAnything.

If I misprint some function name the expectation will simply fail (because the code being tested is calling the correct one), so this is not a point...

For StubOutWithMock: if I won't notice some additional db function call in tested method, and won't stub it StubOutWithMock, it will call the real code and left some garbage in the db. So one more point to protect my solution - using the CreateMockAnything instead of stubbing particular methods lets me to completely cut my db dependency, and I also will see the unexpected method call exception thrown by the MockAnything mock.

So what are the reasons to avoid using of CreateMockAnything()?

Thanks,


Solution

  • The main reason for this is that it is usually good programming practice to only use objects with well defined interfaces, where possible.

    From what I can see in your case, it's a perfectly acceptable use case.