2

I would like to mock a certain module in order to test a piece of code that is using the module.

That is to say, I have a module my_module which I'd like to test. my_module imports an external module real_thing and calls real_thing.compute_something():

#my_module
import real_thing
def my_function():
    return real_thing.compute_something()

I need to mock real_thing so that in a test it will behave like fake_thing, a module that I've created:

#fake_thing
def compute_something():
    return fake_value

The test calls my_module.my_function() which calls real_thing.compute_something():

#test_my_module
import my_module
def test_my_function():
    assert_something(my_module.my_function())

What should I add to the test code so that my_function() will call fake_thing.compute_something() within the test instead of real_thing.compute_something()?

I was trying to figure out how to do so with Mock, but I haven't.

3
  • How about putting import fake_thing as real_thing at the top of your test file? Commented Aug 29, 2012 at 19:11
  • 3
    I always find the easiest way to mock a module is to point directly at it, and shout, "Ha ha, you're a module!" Commented Aug 29, 2012 at 19:31
  • @David: This doesn't solve it. The test executes my_module.my_function() and my_module doesn't know it was called from a test. my_module imports real_thing and therefore real_thing.compute_something() will be executed, no matter what modules are actually imported in the test module. Commented Aug 29, 2012 at 19:35

2 Answers 2

1

Simply that no ? Hack the sys.modules

#fake_thing.py
def compute_something():
    return 'fake_value'

#real_thing.py
def compute_something():
    return 'real_value'

#my_module.py
import real_thing
def my_function():
    return real_thing.compute_something()

#test_my_module.py
import sys

def test_my_function():
    import fake_thing
    sys.modules['real_thing'] = fake_thing
    import my_module
    print my_module.my_function()

test_my_function()

Outputs : 'fake_value'

Sign up to request clarification or add additional context in comments.

4 Comments

The idea behind that is once you squat the module name, python reuses the same one without reloading it.
I've tested it and it doesn't work. my_module.my_function() still doesn't return the fake value; it calls real_thing.calculate_something() and hence returns the real value.
be sure you import my_module after doing the sys.modules trick otherwise it won't work.
I have explicited my test case so you can reproduce it
0

http://code.google.com/p/mockito-python/

>>> from mockito import *
>>> dog = mock()
>>> when(dog).bark().thenReturn("wuff")
>>> dog.bark()
'wuff'

http://technogeek.org/python-module.html - how to replace ,load module dynamically

2 Comments

Your answer as it is doesn't help me because in my question there's one more level of indirection: Let's say dog.bark() calls dog.inhale() and I want to mock dog.inhale() so that in the test, when calling dog.bark(), what would be called is my fake dog.inhale() instead of the real dog.inhale(). How can that be done?
You are right, I added link to Dynamic Module Loading in Python

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.