模拟Python类的方法并返回动态值

时间:2019-01-12 12:12:10

标签: python unit-testing

如何使用Python的unittest.mock模块来模拟使用同一类成员的方法?

class NameHelper(object):
    def __init__(self):
        self.local_id = 0

    def next_id(self):
        self.local_id += 1
        return str(self.local_id)

请注意,我patch.start and patch.stop正在使用setUp方法进行修补:

class TestSomeClient(unittest.TestCase):

    def setUp(self):
        patcher = patch('helpers.name_helper.NameHelper')
        self.addCleanup(patcher.stop)
        self.mock_name_helper = patcher.start()

        # The actual mocked values
        self.mock_name_helper.return_value.local_id = 0
        self.mock_name_helper.return_value.next_id.return_value = 'mock-name'

很显然,模拟名称不是明智的模拟返回值。返回值应使用local_id的{​​{1}}成员。

1 个答案:

答案 0 :(得分:0)

我不确定为什么这个问题没有评论就被否决了。答案是,IMO,不清楚。

patch.start and patch.stop的Python文档提供了以下在setUp中进行修补的示例:

class MyTest(TestCase):
     def setUp(self):
         self.patcher1 = patch('package.module.Class1')
         self.MockClass1 = self.patcher1.start()

     def tearDown(self):
         self.patcher1.stop()

MyTest('test_something').run()

但是,在修补整个类时,这会产生误导。以下内容更有用:

class MockClass1():
    pass

class MyTest(TestCase):
    def setUp(self):
        self.patcher1 = patch('package.module.Class1')
        self.MockClass1 = self.patcher1.start()
        self.MockClass1.return_value = MockClass1()

    def tearDown(self):
        self.patcher1.stop()

请注意,另外一行:

self.MockClass1.return_value = MockClass1()

return_value应该是类MockClass1的新实例。应用于我的示例:

class MockNameHelper(object):
    def __init__(self):
        self.local_id = 0

    def next_id(self):
        self.local_id += 1
        return str(self.local_id)

class TestSomeClient(unittest.TestCase):

    def setUp(self):
        patcher = patch('helpers.name_helper.NameHelper')
        self.addCleanup(patcher.stop)
        self.MockNameHelper = patcher.start()
        self.MockNameHelper.return_value = MockNameHelper()