1

I'm pretty sure I've seen this, but I can't get the syntax right. I want to override a module "constant" during testing. I can write the code like this:

import mymodule

try:
   hold = mymodule.FOO
   mymodule.FOO = 'test value'
   do_something()
finally:
   mymodule.FOO = hold

it seems to me that there should be a way to do this with a "with" statement, something like:

with mymodule.FOO = 'test value':
    do_something()

Is my mind deceiving me? Is there a simple syntax to do what I want?

Chris Curvey
  • 9,738
  • 10
  • 48
  • 70
  • Possible duplicate of [What is the python keyword "with" used for?](http://stackoverflow.com/questions/1369526/what-is-the-python-keyword-with-used-for) – OneCricketeer Jan 13 '16 at 20:48
  • I know, not "duplicate", but the assignment operator of `=` for the variable definition you want does not know how to reassign the constant after it is finished – OneCricketeer Jan 13 '16 at 20:49

2 Answers2

6

Sounds like you want unittest.mock.patch:

from unittest.mock import patch

with patch('mymodule.Foo', 'test value'):
    do_whatever()

If you're on a Python version prior to 3.3, unittest.mock doesn't exist, but there's a backport available on PyPI. You could also write your own context manager to do this. However, there is nothing to do this built into the syntax.

user2357112
  • 260,549
  • 28
  • 431
  • 505
1

Generally this is called monkeypatching.

unittest.mock provides helper methods for this (as seen in another answer), but outside of the Python stdlib, I'd recommend looking at py.test's monkeypatching fixture:

def test_foo(monkeypatch):
    monkeypatch.setattr('mymodule.FOO', 'test value')
    # more code here
    # ...

    # the monkeypatch is automatically reverted at the end of the test
Markus Unterwaditzer
  • 7,992
  • 32
  • 60