What is the difference between using "@ patch.object" and "with patch.object" in Python?

When writing unit tests for my application, I always used decorators @mock.patchand @patch.object. But now, for some unit tests, when I use the decorator, I get the error " TypeError: staticmethod object is not an iterator ."

But with the same code, if I use mock.patch.objector mock.patch.object, everything works fine.

For example, in my test class, I have this method:

@staticmethod
def my_mock():
   ...do something

When I try to execute unit test

@mock.patch('mypackage.mymodule.my_method', side_effect=my_mock)
def test_something(self, my_method_mocked):
    ...test something

I get an error message before TypeError: the staticmethod object is not an iterator .

But when I try this way

def test_something(self):
    with patch.object(mymodule, "my_method") as mocked_method:
        mocked_method.side_effect = self.my_mock
        ...test something

then everything works fine.

Python , .

? ?

, :

class TestClass(unittest.TestCase):

    @staticmethod
    def my_mock():
    ...mock
        return service

    # doesn't work
    @mock.patch('mypackage.mymodule.my_method', side_effect=my_mock)
    def test_something(self, my_method_mocked):
        ...test something

    # work 
    def test_something(self):
    with patch.object(mymodule, "my_method") as mocked_method:
        mocked_method.side_effect = self.my_mock
        ...test something

TestClass.my_mock. , .

+4
2

Python. , patch, , side_effect .

class A(object):
    @staticmethod
    def my_mock():
        pass

    print type(my_mock)    # As in your decorator case

# As in your context manager case
print type(A.my_mock)
print type(A().my_mock)

, , print <type 'staticmethod'>, .

print <type 'function'>, ; __get__.

print type(A.__dict__['my_mock'].__get__(A))
print type(A.__dict__['my_mock'].__get__(A()))

. https://docs.python.org/2/howto/descriptor.html , (, ).


- , patch , side_effect, . staticmethod , . (: A.__dict__['my_mock']().)

, , .

class Foo(object):
    @staticmethod
    def my_mock():
        "whatever it does"

@mock.patch('mypackage.mymodule.my_method', side_effect=Foo.my_mock)
def test_something(self, my_method_mocked):
    ...test something
+1

,

class mymodule:
    @staticmethod
    def my_mock():
        ...do something
...

@mock.patch('mypackage.mymodule.my_method', side_effect=mymodule.my_mock)
def test_something(self, my_method_mocked):
    ...test something
0

Source: https://habr.com/ru/post/1650838/


All Articles