繁体   English   中英

Python unittest模拟配置不会扩散到测试方法

[英]Python unittest mock configuration not proliferating to test method

我有一个想在测试中模拟的复杂类。 但是,我希望能够在我的模拟类上设置一个特定的属性,以便我的被测函数能够正常工作。 下面是具有实际和预期输出的简单,可运行的示例。

在我的示例中,为什么我的模拟配置不会激增到my_module.instantiate_class_do_stuff 显然, MyClass确实在被嘲笑,但是我配置MyClass.a的模仿的尝试并没有坚持。

目录tmp内容:

tmp
├── __init__.py
├── my_module.py
└── test_my_module.py

请注意__init__.py为空。

文件my_module.py内容:

class MyClass:
    def __init__(self):
        # Do expensive operations that will be mocked in testing.
        self.a = 7


def instantiate_class_do_stuff():
    """Create MyClass instance and do stuff with it"""
    instance = MyClass()
    print('Value of a in instantiate_class_call_method: {}'.format(instance.a))
    # Do stuff with instance...

文件test_my_module.py内容:

import unittest
from unittest.mock import patch
from tmp import my_module


class MyTestCase(unittest.TestCase):
    def setUp(self):
        print('*' * 79)

    def test_create_class_call_method_1(self):
        """Try using the Mock's configure_mock method."""

        with patch('tmp.my_module.MyClass') as p:
            p.configure_mock(a=10)
            print('Value of a in test_create_class_call_method_1: {}'
                  .format(p.a))
            my_module.instantiate_class_do_stuff()

        self.assertTrue(True)

    def test_create_class_call_method_2(self):
        """Try passing in kwargs to patch, which should make it to
        configure_mock, according to the docs.
        """

        with patch('tmp.my_module.MyClass', a=10) as p:
            print('Value of a in test_create_class_call_method_2: {}'
                  .format(p.a))
            my_module.instantiate_class_do_stuff()

        self.assertTrue(True)

    def test_create_class_call_method_alternate_2(self):
        """Try using patch.object instead of plain patch."""

        with patch.object(my_module, 'MyClass', a=10) as p:
            print('Value of a in test_create_class_call_method_3: {}'
                  .format(p.a))
            my_module.instantiate_class_do_stuff()

        self.assertTrue(True)


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

运行test_my_module.py实际输出:

*******************************************************************************
Value of a in test_create_class_call_method_1: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598201104'>
*******************************************************************************
Value of a in test_create_class_call_method_2: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598270096'>
*******************************************************************************
Value of a in test_create_class_call_method_3: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598347088'>

来自运行test_my_module.py预期输出:

*******************************************************************************
Value of a in test_create_class_call_method_1: 10
Value of a in instantiate_class_call_method: 10
*******************************************************************************
Value of a in test_create_class_call_method_2: 10
Value of a in instantiate_class_call_method: 10
*******************************************************************************
Value of a in test_create_class_call_method_3: 10
Value of a in instantiate_class_call_method: 10

那么,当被测函数实际运行时,如何使属性配置有效?

我发布了类似(但不同)的问题,但没有得到特别令人满意的答案

好吧,这对我来说当然不是很直观,但是我发现了。

我注意到在我的测试方法中, p的值( MyClass__repr__实例)具有__repr__<MagicMock name='MyClass' id='140054079807440'>

然而,在测试中,在函数内部instantiate_class_do_stuff ,的值instance具有__repr__<MagicMock name='MyClass()' id='140054079941392'> 区别在于MyClass之后的()

因此,看来我不是在模拟正确的东西-我想在MyClass返回值上模拟a属性。

因此,工作测试如下所示:

def test_creat_class_call_method(self):
    # Create a mock which will be returned by MyClass.
    m = MagicMock()
    m.a = 10

    with patch('tmp.my_module.MyClass', return_value=m) as p:
        my_module.instantiate_class_do_stuff()

并且my_module.instantiate_class_do_stuffprint语句打印以下内容:

Value of a in instantiate_class_do_stuff: 10

成功!

暂无
暂无

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

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