Python @patch not working

2020-08-14 10:33发布

问题:

I am trying to test a method that within it creates an instance of another class, I am attempting to mock the creation of the inner class... That is not working for me. I tried replicating the problem to a simplified case - and still no go. Here is the simplified case:

I have a directory named pymock with a __init__.py in it. Other than that there are these 3 files:

foo.py

#!/usr/bin/python
class Foo(object):
    def foo1(self):
        return 1

goo.py

#!/usr/bin/python
from foo import Foo


class Goo(object):
    def goo1(self):
        f = Foo()
        return f.foo1()

goo_test.py

#!/usr/bin/python
from mock import patch, Mock
from nose.tools import assert_equal

from goo import Goo


class TestGoo(object):
    def setup(self):
        self.goo = Goo()

    @patch('pymock.foo.Foo', autospec=True)
    def test_goo1(self, foo1_mock):
        foo_instance = Mock()
        foo1_mock.return_value = foo_instance
        foo_instance.foo1.return_value = 11
        assert_equal(11, self.goo.goo1())

Thanks in advance!

回答1:

You need to patch the name that goo is using.

@patch('pymock.goo.Foo', autospec=True)


回答2:

Basically it's how you import functions/classes. In goo.py you've imported Foo directly. So goo.py has it's own reference to Foo, so your patch will have to be: @patch('pymock.goo.Foo', autospec=True)

But if goo.py looked like this:

#!/usr/bin/python
import foo


class Goo(object):
    def goo1(self):
        f = foo.Foo()
        return f.foo1()

the patch in your question would work since goo.py doesn't have a direct reference to Foo