How to patch a regular function in another module in Python unit tests?











up vote
-1
down vote

favorite












I'm trying to patch a function defined in a different module from the module containing the testing code. If the function and its test are defined in the same module, I've found that the following works:



import unittest
from mock import patch


def foo():
return 'bar'


class FooTest(unittest.TestCase):
@patch('__main__.foo')
def test_foo(self, mock_foo):
mock_foo.return_value = 'baz'

foo()

mock_foo.assert_called()


if __name__ == "__main__":
unittest.main()


Moreover, if I drop into the debugger in test function just before the foo() call, I see that foo is a MagicMock instance, and that if I call it, it returns 'baz' (not 'bar') as expected.



I've tried to adapt this somewhat as follows. In the same directory, I've written a foo_module.py containing just the definition of foo():



def foo():
return 'bar'


and I've imported this function in the testing module and changed the patch() argument from __main__.foo to foo_module.foo:



import unittest
from mock import patch
from foo_module import foo


class FooTest(unittest.TestCase):
@patch('foo_module.foo')
def test_foo(self, mock_foo):
mock_foo.return_value = 'baz'

foo()

mock_foo.assert_called()


if __name__ == "__main__":
unittest.main()


However, if I try to run this, I get an AssertionError because the mock_foo was not called:



$ python use_patch.py
F
======================================================================
FAIL: test_foo (__main__.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
return func(*args, **keywargs)
File "use_patch.py", line 13, in test_foo
mock_foo.assert_called()
File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 906, in assert_called
raise AssertionError(msg)
AssertionError: Expected 'foo' to have been called.

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)


Indeed now if I drop into the debugger, foo is an ordinary function and no longer a MagicMock instance, and it returns 'bar' instead of 'baz':



$ python use_patch.py
> /Users/kupeek/Documents/Scratch/use_patch.py(11)test_foo()
10 import ipdb; ipdb.set_trace()
---> 11 foo()
12

ipdb> foo
<function foo at 0x107347410>
ipdb> mock_foo
<MagicMock name='foo' id='4429017168'>
ipdb> foo()
'bar'


Any idea why this is not working? I've consulted the docs (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) but to no avail so far...










share|improve this question


























    up vote
    -1
    down vote

    favorite












    I'm trying to patch a function defined in a different module from the module containing the testing code. If the function and its test are defined in the same module, I've found that the following works:



    import unittest
    from mock import patch


    def foo():
    return 'bar'


    class FooTest(unittest.TestCase):
    @patch('__main__.foo')
    def test_foo(self, mock_foo):
    mock_foo.return_value = 'baz'

    foo()

    mock_foo.assert_called()


    if __name__ == "__main__":
    unittest.main()


    Moreover, if I drop into the debugger in test function just before the foo() call, I see that foo is a MagicMock instance, and that if I call it, it returns 'baz' (not 'bar') as expected.



    I've tried to adapt this somewhat as follows. In the same directory, I've written a foo_module.py containing just the definition of foo():



    def foo():
    return 'bar'


    and I've imported this function in the testing module and changed the patch() argument from __main__.foo to foo_module.foo:



    import unittest
    from mock import patch
    from foo_module import foo


    class FooTest(unittest.TestCase):
    @patch('foo_module.foo')
    def test_foo(self, mock_foo):
    mock_foo.return_value = 'baz'

    foo()

    mock_foo.assert_called()


    if __name__ == "__main__":
    unittest.main()


    However, if I try to run this, I get an AssertionError because the mock_foo was not called:



    $ python use_patch.py
    F
    ======================================================================
    FAIL: test_foo (__main__.FooTest)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
    File "use_patch.py", line 13, in test_foo
    mock_foo.assert_called()
    File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 906, in assert_called
    raise AssertionError(msg)
    AssertionError: Expected 'foo' to have been called.

    ----------------------------------------------------------------------
    Ran 1 test in 0.001s

    FAILED (failures=1)


    Indeed now if I drop into the debugger, foo is an ordinary function and no longer a MagicMock instance, and it returns 'bar' instead of 'baz':



    $ python use_patch.py
    > /Users/kupeek/Documents/Scratch/use_patch.py(11)test_foo()
    10 import ipdb; ipdb.set_trace()
    ---> 11 foo()
    12

    ipdb> foo
    <function foo at 0x107347410>
    ipdb> mock_foo
    <MagicMock name='foo' id='4429017168'>
    ipdb> foo()
    'bar'


    Any idea why this is not working? I've consulted the docs (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) but to no avail so far...










    share|improve this question
























      up vote
      -1
      down vote

      favorite









      up vote
      -1
      down vote

      favorite











      I'm trying to patch a function defined in a different module from the module containing the testing code. If the function and its test are defined in the same module, I've found that the following works:



      import unittest
      from mock import patch


      def foo():
      return 'bar'


      class FooTest(unittest.TestCase):
      @patch('__main__.foo')
      def test_foo(self, mock_foo):
      mock_foo.return_value = 'baz'

      foo()

      mock_foo.assert_called()


      if __name__ == "__main__":
      unittest.main()


      Moreover, if I drop into the debugger in test function just before the foo() call, I see that foo is a MagicMock instance, and that if I call it, it returns 'baz' (not 'bar') as expected.



      I've tried to adapt this somewhat as follows. In the same directory, I've written a foo_module.py containing just the definition of foo():



      def foo():
      return 'bar'


      and I've imported this function in the testing module and changed the patch() argument from __main__.foo to foo_module.foo:



      import unittest
      from mock import patch
      from foo_module import foo


      class FooTest(unittest.TestCase):
      @patch('foo_module.foo')
      def test_foo(self, mock_foo):
      mock_foo.return_value = 'baz'

      foo()

      mock_foo.assert_called()


      if __name__ == "__main__":
      unittest.main()


      However, if I try to run this, I get an AssertionError because the mock_foo was not called:



      $ python use_patch.py
      F
      ======================================================================
      FAIL: test_foo (__main__.FooTest)
      ----------------------------------------------------------------------
      Traceback (most recent call last):
      File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
      return func(*args, **keywargs)
      File "use_patch.py", line 13, in test_foo
      mock_foo.assert_called()
      File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 906, in assert_called
      raise AssertionError(msg)
      AssertionError: Expected 'foo' to have been called.

      ----------------------------------------------------------------------
      Ran 1 test in 0.001s

      FAILED (failures=1)


      Indeed now if I drop into the debugger, foo is an ordinary function and no longer a MagicMock instance, and it returns 'bar' instead of 'baz':



      $ python use_patch.py
      > /Users/kupeek/Documents/Scratch/use_patch.py(11)test_foo()
      10 import ipdb; ipdb.set_trace()
      ---> 11 foo()
      12

      ipdb> foo
      <function foo at 0x107347410>
      ipdb> mock_foo
      <MagicMock name='foo' id='4429017168'>
      ipdb> foo()
      'bar'


      Any idea why this is not working? I've consulted the docs (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) but to no avail so far...










      share|improve this question













      I'm trying to patch a function defined in a different module from the module containing the testing code. If the function and its test are defined in the same module, I've found that the following works:



      import unittest
      from mock import patch


      def foo():
      return 'bar'


      class FooTest(unittest.TestCase):
      @patch('__main__.foo')
      def test_foo(self, mock_foo):
      mock_foo.return_value = 'baz'

      foo()

      mock_foo.assert_called()


      if __name__ == "__main__":
      unittest.main()


      Moreover, if I drop into the debugger in test function just before the foo() call, I see that foo is a MagicMock instance, and that if I call it, it returns 'baz' (not 'bar') as expected.



      I've tried to adapt this somewhat as follows. In the same directory, I've written a foo_module.py containing just the definition of foo():



      def foo():
      return 'bar'


      and I've imported this function in the testing module and changed the patch() argument from __main__.foo to foo_module.foo:



      import unittest
      from mock import patch
      from foo_module import foo


      class FooTest(unittest.TestCase):
      @patch('foo_module.foo')
      def test_foo(self, mock_foo):
      mock_foo.return_value = 'baz'

      foo()

      mock_foo.assert_called()


      if __name__ == "__main__":
      unittest.main()


      However, if I try to run this, I get an AssertionError because the mock_foo was not called:



      $ python use_patch.py
      F
      ======================================================================
      FAIL: test_foo (__main__.FooTest)
      ----------------------------------------------------------------------
      Traceback (most recent call last):
      File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
      return func(*args, **keywargs)
      File "use_patch.py", line 13, in test_foo
      mock_foo.assert_called()
      File "/Users/kupeek/Documents/Scratch/venv/lib/python2.7/site-packages/mock/mock.py", line 906, in assert_called
      raise AssertionError(msg)
      AssertionError: Expected 'foo' to have been called.

      ----------------------------------------------------------------------
      Ran 1 test in 0.001s

      FAILED (failures=1)


      Indeed now if I drop into the debugger, foo is an ordinary function and no longer a MagicMock instance, and it returns 'bar' instead of 'baz':



      $ python use_patch.py
      > /Users/kupeek/Documents/Scratch/use_patch.py(11)test_foo()
      10 import ipdb; ipdb.set_trace()
      ---> 11 foo()
      12

      ipdb> foo
      <function foo at 0x107347410>
      ipdb> mock_foo
      <MagicMock name='foo' id='4429017168'>
      ipdb> foo()
      'bar'


      Any idea why this is not working? I've consulted the docs (https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) but to no avail so far...







      python mocking python-unittest






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 19 at 20:51









      Kurt Peek

      9,1361867133




      9,1361867133
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          I managed to get the example to work by, instead of from foo_module import foo and calling foo(), doing import foo_module followed by foo_module.foo():



          import unittest
          from mock import patch
          import foo_module


          class FooTest(unittest.TestCase):
          @patch('foo_module.foo')
          def test_foo(self, mock_foo):
          mock_foo.return_value = 'baz'

          foo_module.foo()

          mock_foo.assert_called()


          if __name__ == "__main__":
          unittest.main()


          Basically the patch() decorator determines a target and an attribute, and internally replaces that attribute by a mock instance, along the lines of



          setattr(target, attribute, MagicMock())



          In the original example, the foo() function was being imported directly and was not an 'attribute' of the foo_module, so the patcher was not patching the intended object.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382446%2fhow-to-patch-a-regular-function-in-another-module-in-python-unit-tests%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote



            accepted










            I managed to get the example to work by, instead of from foo_module import foo and calling foo(), doing import foo_module followed by foo_module.foo():



            import unittest
            from mock import patch
            import foo_module


            class FooTest(unittest.TestCase):
            @patch('foo_module.foo')
            def test_foo(self, mock_foo):
            mock_foo.return_value = 'baz'

            foo_module.foo()

            mock_foo.assert_called()


            if __name__ == "__main__":
            unittest.main()


            Basically the patch() decorator determines a target and an attribute, and internally replaces that attribute by a mock instance, along the lines of



            setattr(target, attribute, MagicMock())



            In the original example, the foo() function was being imported directly and was not an 'attribute' of the foo_module, so the patcher was not patching the intended object.






            share|improve this answer

























              up vote
              0
              down vote



              accepted










              I managed to get the example to work by, instead of from foo_module import foo and calling foo(), doing import foo_module followed by foo_module.foo():



              import unittest
              from mock import patch
              import foo_module


              class FooTest(unittest.TestCase):
              @patch('foo_module.foo')
              def test_foo(self, mock_foo):
              mock_foo.return_value = 'baz'

              foo_module.foo()

              mock_foo.assert_called()


              if __name__ == "__main__":
              unittest.main()


              Basically the patch() decorator determines a target and an attribute, and internally replaces that attribute by a mock instance, along the lines of



              setattr(target, attribute, MagicMock())



              In the original example, the foo() function was being imported directly and was not an 'attribute' of the foo_module, so the patcher was not patching the intended object.






              share|improve this answer























                up vote
                0
                down vote



                accepted







                up vote
                0
                down vote



                accepted






                I managed to get the example to work by, instead of from foo_module import foo and calling foo(), doing import foo_module followed by foo_module.foo():



                import unittest
                from mock import patch
                import foo_module


                class FooTest(unittest.TestCase):
                @patch('foo_module.foo')
                def test_foo(self, mock_foo):
                mock_foo.return_value = 'baz'

                foo_module.foo()

                mock_foo.assert_called()


                if __name__ == "__main__":
                unittest.main()


                Basically the patch() decorator determines a target and an attribute, and internally replaces that attribute by a mock instance, along the lines of



                setattr(target, attribute, MagicMock())



                In the original example, the foo() function was being imported directly and was not an 'attribute' of the foo_module, so the patcher was not patching the intended object.






                share|improve this answer












                I managed to get the example to work by, instead of from foo_module import foo and calling foo(), doing import foo_module followed by foo_module.foo():



                import unittest
                from mock import patch
                import foo_module


                class FooTest(unittest.TestCase):
                @patch('foo_module.foo')
                def test_foo(self, mock_foo):
                mock_foo.return_value = 'baz'

                foo_module.foo()

                mock_foo.assert_called()


                if __name__ == "__main__":
                unittest.main()


                Basically the patch() decorator determines a target and an attribute, and internally replaces that attribute by a mock instance, along the lines of



                setattr(target, attribute, MagicMock())



                In the original example, the foo() function was being imported directly and was not an 'attribute' of the foo_module, so the patcher was not patching the intended object.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 19 at 22:46









                Kurt Peek

                9,1361867133




                9,1361867133






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382446%2fhow-to-patch-a-regular-function-in-another-module-in-python-unit-tests%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                    Alcedinidae

                    RAC Tourist Trophy