Mocking in tests breaks coverage

Issue #452 invalid
Krzysztof Pawlik created an issue

Mocking in tests breaks coverage: coverage will fail to write the .coverage file (mock intercepts the open() call). To work around this it would be ok to either isolate_module() builtins or use os.fdopen()/ pair like in snippet

Comments (5)

  1. Ned Batchelder repo owner

    @nelchael Thanks for the report. Can you provide a small test case to reproduce the issue?

  2. Krzysztof Pawlik reporter

    Sure, this is simple case that shows the error:

    import __builtin__
    import mox
    import StringIO
    import unittest
    class TestedClass(object):
            def doIt(self):
                    f = open('/dev/shm/foo', 'w')
                    return True
    class TestForTestedClass(unittest.TestCase):
            def setUp(self):
                    self.mox = mox.Mox()
            def tearDown(self):
            def test(self):
                    self.mox.StubOutWithMock(__builtins__, 'open')
          '/dev/shm/foo', 'w').AndReturn(StringIO.StringIO())
                    testedClass = TestedClass()
    if __name__ == '__main__':

    And the error:

    Traceback (most recent call last):
      File "/home/nelchael/.local/bin/coverage", line 9, in <module>
        load_entry_point('coverage==4.0.3', 'console_scripts', 'coverage')()
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 741, in main
        status = CoverageScript().command_line(argv)
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 481, in command_line
        return self.do_run(options, args)
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 631, in do_run
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 765, in save
        self.data_files.write(, suffix=self.data_suffix)
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 665, in write
      File "/home/nelchael/.local/lib/python2.7/site-packages/coverage/", line 458, in write_file
        with open(filename, 'w') as fdata:
      File "/usr/lib/python2.7/site-packages/", line 1000, in __call__
        expected_method = self._VerifyMethodCall()
      File "/usr/lib/python2.7/site-packages/", line 1047, in _VerifyMethodCall
        expected = self._PopNextMethod()
      File "/usr/lib/python2.7/site-packages/", line 1033, in _PopNextMethod
        raise UnexpectedMethodCallError(self, None)
    mox.UnexpectedMethodCallError: Unexpected method call Stub for <built-in function open>.__call__('/home/nelchael/.coverage', 'w') -> None

    I've changed to this:

        def write_file(self, filename):
            """Write the coverage data to `filename`."""
            if self._debug and self._debug.should('dataio'):
                self._debug.write("Writing data to %r" % (filename,))
            with os.fdopen(, os.O_WRONLY|os.O_CREAT), 'w') as fdata:
  3. Ned Batchelder repo owner

    A better approach would be to narrow your mock. If you are using open in, instead of mocking "", mock "". That way, only the use of open in your file will be affected. Would that work?

  4. Ned Batchelder repo owner

    I'm going to close this issue. I don't think it's reasonable for coverage to try to avoid the standard library so that overly aggressive mocks will continue to work. Maybe I'm wrong. Let me know.

  5. Log in to comment