Mocking out methods on any instance of a python class
Question: I want to mock out methods on any instance of some class in the production
code in order to facilitate testing. Is there any library in Python which
could facilitate this?

Basically, I want to do the following, but in Python (the following code is
Ruby, using the Mocha library):

    
    
      def test_stubbing_an_instance_method_on_all_instances_of_a_class
        Product.any_instance.stubs(:name).returns('stubbed_name')
        assert_equal 'stubbed_name', SomeClassThatUsesProduct.get_new_product_name
      end
    

The important thing to note from above is that I need to mock it out on the
class level, since I'm actually need to mock out methods on an instance
created by the thing I'm testing.

Use Case:

I have a class `QueryMaker` which calls a method on an instance of
`RemoteAPI`. I want to mock out the `RemoteAPI.get_data_from_remote_server`
method to return some constant. How do I do this inside a test without having
to put a special case within the `RemoteAPI` code to check for what
environment it's running in.

Example of what I wanted in action:

    
    
    # a.py
    class A(object):
        def foo(self):
            return "A's foo"
    
    # b.py
    from a import A
    
    class B(object):
        def bar(self):
            x = A()
            return x.foo()
    
    # test.py
    from a import A
    from b import B
    
    def new_foo(self):
        return "New foo"
    
    A.foo = new_foo
    
    y = B()
    if y.bar() == "New foo":
        print "Success!"
    


Answer: Needing to mock out methods when testing is very common and there are lots of
tools to help you with it in Python. The danger with "monkey patching" classes
like this is that if you don't _undo_ it afterwards then the class has been
modified for all other uses throughout your tests.

My library mock, which is one of the most popular Python mocking libraries,
includes a helper called "patch" that helps you to safely patch methods or
attributes on objects and classes during your tests.

The mock module is available from:

<http://pypi.python.org/pypi/mock>

The patch decorator can be used as a context manager or as a test decorator.
You can either use it to patch out with functions yourself, or use it to
automatically patch with Mock objects that are very configurable.

    
    
    from a import A
    from b import B
    
    from mock import patch
    
    def new_foo(self):
        return "New foo"
    
    with patch.object(A, 'foo', new_foo):
        y = B()
        if y.bar() == "New foo":
            print "Success!"
    

This handles the unpatching for you automatically. You could get away without
defining the mock function yourself:

    
    
    from mock import patch
    
    with patch.object(A, 'foo') as mock_foo:
        mock_foo.return_value = "New Foo"
    
        y = B()
        if y.bar() == "New foo":
            print "Success!"
    

