简体   繁体   English

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

[英]Mock the method of a Python class and return a dynamic value

How can Python's unittest.mock module be used to mock a method that uses a member of the same class?如何使用 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)

Note, I'm patch.start and patch.stop to do patching in the setUp method:注意,我在setUp方法中使用patch.start 和 patch.stop进行修补:

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'

Clearly, mock-name is not a sensible mock return value.显然, mock-name不是一个合理的模拟返回值。 The return value should use the local_id member of NameHelper .返回值应使用local_id成员NameHelper

I'm unsure why the question was down-voted with no comments.我不确定为什么这个问题在没有评论的情况下被否决了。 The answer is, IMO, not clear.答案是,IMO,不清楚。

The Python documentation for patch.start and patch.stop , provides the following example for patching in setUp: patch.start 和 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()

However, when patching entire class, this is misleading.但是,在修补整个类时,这是一种误导。 The following is more helpful:以下内容更有帮助:

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()

Note, the additional line:请注意,附加行:

self.MockClass1.return_value = MockClass1()

The return_value should be a new instance of the class MockClass1 . return_value应该是类MockClass1的新实例。 Applied to my example:应用于我的例子:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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