Q:

In Python 3 how can I patch a function inside a module for unit testing?

I have decorated methods that send timings to a hosted graphite instance they look like what is below
views.py
from util import send_timing

@send_timing('login')
def login_user():

    if is_user_ok():
        return True
    return False

@send_timing('get_user_info')
def get_user_info():

    return get_that_info()

I have a util file that defines the decorator
util.py
def send_timing(f):
  def decorated(*args):
     make_network_connection()
     ret = f(*args)
  return decorated

I have some unit tests
test.py
from views import *
import unittest

class TestCase(unittest.TestCase):

   def test_login(self):         
      self.assertTrue(login_user())

Now the problem is that call to login_user. It invokes the send_timing decorator which in turn makes a network connection. This makes my tests volatile and non-deterministic. Is there an easy way (python 3.3) to patch send_timing with a dummy or mock globally for all my tests?

A:

You want to use @functools.wraps() decorator factory in your decorator:
from functools import wraps

def send_timing(f):
    @wraps(f)
    def wrapper(*args, **kw):
        # probably do a little more than just proxy
        return f(*args, **kw)
    return wrapper

This adds an attribute on the returned wrapper function, letting you access the original unwrapped function:
unwrapped = login_user.__wrapped__

You can use the unwrapped value here to mock login_user, or use it directly in your unit tests.

