简体   繁体   中英

How to Mock Instance Method in Python

Consider the following three files.

# my_class.py

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5


# main.py

from my_class import MyClass

def my_func():
    instance = MyClass()
    instance.do_thing()


# test_main.py

from main import my_func
from unittest.mock import patch

@patch('main.MyClass')
def test_my_func(MockMyClass):
    my_func()
    MockMyClass.do_thing.assert_called_once()

AssertionError: Expected 'do_thing' to have been called once. Called 0 times.

I'm instantiating a class MyClass inside a driver function my_func and calling one of the class's methods do_thing . What I'd like to do is test that when the driver function is invoked, the method of the class is called exactly once. I'm encountering an assertion error that's giving me problems.

I've read a million and one SO posts and other resources online about Python mocks, but I'm not able to figure this out. I thought the trick was that the @patch decorator patches the namespace the module is imported into, not from [ Python Mocking a function from an imported module . What am I doing wrong here?

The do_thing method is an instance method of MyClass , NOT class method. You assert MockMyClass.do_thing.assert_called_once() is not correct. Here is the unit test solution:

my_class.py :

class MyClass:
    def __init__(self):
        pass

    def do_thing(self):
        return 5

main.py :


from my_class import MyClass


def my_func():
    instance = MyClass()
    instance.do_thing()

test_main.py :

from main import my_func
import unittest
from unittest.mock import patch


class TestMain(unittest.TestCase):
    @patch('main.MyClass')
    def test_my_func(self, MockMyClass):
        mock_my_class_instance = MockMyClass.return_value
        my_func()
        mock_my_class_instance.do_thing.assert_called_once()


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

unit test results with coverage report:

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

OK
Name                                      Stmts   Miss  Cover   Missing
-----------------------------------------------------------------------
src/stackoverflow/60539392/main.py            4      0   100%
src/stackoverflow/60539392/my_class.py        5      2    60%   3, 6
src/stackoverflow/60539392/test_main.py      10      0   100%
-----------------------------------------------------------------------
TOTAL

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM