Hacker News new | ask | show | jobs
by jabwork 2515 days ago
I've wrestled with this problem several times. My conclusion was mocks are just fine, but this is a wart in that there isn't "one way to do it"

For the most part I can get by with one rule: always mock the module.

  with mock.patch('os.listdir'):
will always work, even if it doesn't accomplish what you want.

  with mock.patch('mymodule.os.listdir')
will fail if that module does not explicitly import os and instead does something like from os import listdir (perhaps because a later dev did not realize importing os directly was actually a requirement for the test and changed the code).

The rule is not perfect though. In the above case, the error will actually be

  ImportError: No module named os
This can be fixed with e.g.,

  assert hasattr(module, 'os'), "os module is not explicitly imported"
as a preamble to your test but ... it is not perfect by any means.

EDIT: formatting

1 comments

I don't understand what you mean by "will always work, even if it doesn't accomplish what you want." Mocking os.listdir will be useless if your product code's imports don't match it. How is this "one rule" to use?
The os module ships with python, so the function call mocking os.listdir will always succeed even if the code being tested does not use os.listdir

By mocking mymodule.os.listdir you add a requirement that mymodule actually import the os module and take advantage of mock.patch failing loudly if it does not.