views:

99

answers:

3

I got a function in a certain module that I want to redefine(mock) at runtime for testing purposes. As far as I understand, function definition is nothing more than an assignment in python(the module definition itself is a kind of function being executed). As I said, I wanna do this in the setup of a test case, so the function to be redefined lives in another module. What is the syntax for doing this? For example, 'module1' is my module and 'func1' is my function, in my testcase I have tried this (no success):

import module1

module1.func1 = lambda x: return True
+1  A: 

Just assign a new function or lambda to the old name:

>>> def f(x):
...     return x+1
... 
>>> f(3)
4
>>> def new_f(x):
...     return x-1
... 
>>> f = new_f
>>> f(3)
2

It works also when a function is from another module:

### In other.py:
# def f(x):
#    return x+1
###

import other

other.f = lambda x: x-1

print other.f(1)   # prints 0, not 2
jetxee
As I said, the function is in another module, check my edit.
Thiado de Arruda
It works the same. I updated the answer.
jetxee
+6  A: 
import module1
import unittest

class MyTest(unittest.TestCase):
    def setUp(self):
        # Replace othermod.function with our own mock
        self.old_func1 = module1.func1
        module1.func1 = self.my_new_func1

    def tearDown(self):
        module1.func1 = self.old_func1

    def my_new_func1(self, x):
        """A mock othermod.function just for our tests."""
        return True

    def test_func1(self):
        module1.func1("arg1")

Lots of mocking libraries provide tools for doing this sort of mocking, you should investigate them as you will likely get a good deal of help from them.

Ned Batchelder
Do you know if I can redefine the function using a closure?
Thiado de Arruda
You could also use a lambda as you did in your example, it doesn't have to be a method.
Ned Batchelder
+1  A: 
import foo

def bar(x):
    pass

foo.bar = bar
leoluk