0

I have a module that I need to test in python.

I'm using the unittest framework but I ran into a problem.

The module has some method definitions, one of which is used when it's imported (readConfiguration) like so:

.
.
.
def readConfiguration(file = "default.xml"):
    # do some reading from xml

readConfiguration()

This is a problem because when I try to import the module it also tries to run the "readConfiguration" method which fails the module and the program (a configuration file does not exist in the test environment).

I'd like to be able to test the module independent of any configuration files.

I didn't write the module and it cannot be re-factored.

I know I can include a dummy configuration file but I'm looking for a "cleaner", more elegant, solution.

4
  • 1
    There is no cleaner solution; this is one of those things you cannot patch out at runtime. Commented Oct 6, 2013 at 8:30
  • Without more information, there really is not much we can help you with. But it seems that if you want to work around this, you will need to patch, modify, or refactor the module. There is no magical solution. Commented Oct 6, 2013 at 8:31
  • patch as in re-factor? Commented Oct 6, 2013 at 8:32
  • 3
    Yes, Inbar meant refactor. Forcing a config load at import time is terribly bad practice. Commented Oct 6, 2013 at 8:33

1 Answer 1

1

As commenters have already pointed out, imports should never have side effects, so try to get the module changed if at all possible.

If you really, absolutely, cannot do this, there might be another way: let readConfiguration() be called, but stub out its dependencies. For instance, if it uses the builtin open() function, you could mock that, as demonstrated in the mock documentation:

>>> mock = MagicMock(return_value=sentinel.file_handle)
>>> with patch('builtins.open', mock):
...     import the_broken_module
...     # do your testing here

Replace sentinel.file_handle with StringIO("<contents of mock config file>") if you need to supply actual content.

It's brittle as it depends on the implementation of readConfiguration(), but if there really is no other way, it might be useful as a last resort.

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

3 Comments

Thanks, this is a nice patch but probably does not fit a standard unittest structure. I may resort to it if re-factoring will not be approved after re-examination but for now it's on hold as no good solution was suggested (other than... re-factoring).
If you need it from more than one test method, you can do this in the setUp() method of your unittest class, and do e.g. import the_broken_module; self.the_broken_module = the_broken_module. You can then access it from test methods as self.the_broken_module. Once imported, any subsequent imports won't have any effect but don't do any harm either.
It seems to work (the program doesn't break, but no tests are written yet). If we'll end up using it I'll let you know how well it did. Thanks!

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.