你如何模拟修补python类并为每个实例化获取一个新的Mock对象?

bav*_*aza 26 python mocking python-mock python-unittest

好的,
我知道这在手册中有提及,可能side_effect与/和/有关return_value,但一个简单直接的例子对我帮助很大.

我有:

class ClassToPatch():
   def __init__(self, *args):
       _do_some_init_stuff()

   def some_func():
       _do_stuff()


class UUT():
    def __init__(self, *args)
       resource_1 = ClassToPatch()
       resource_2 = ClassToPatch()
Run Code Online (Sandbox Code Playgroud)

现在,我想对这个UUT类进行单元测试,然后嘲笑ClassToPatch.知道UUT该类将实例化两个ClassToPatch对象,我希望Mock框架为每个实例化返回一个新的Mock对象,所以我可以稍后在每个实例上断言.

如何@patch在测试用例中使用装饰器实现此目的?即,如何修复以下代码示例?

class TestCase1(unittest.TestCase):

    @patch('classToPatch.ClassToPatch',autospec=True)
    def test_1(self,mock1,mock2):
        _assert_stuff()
Run Code Online (Sandbox Code Playgroud)

srg*_*erg 29

这是一个让你前进的快速例子:

import mock
import unittest

class ClassToPatch():
   def __init__(self, *args):
       pass

   def some_func(self):
       return id(self)

class UUT():
    def __init__(self, *args):
        resource_1 = ClassToPatch()
        resource_2 = ClassToPatch()
        self.test_property = (resource_1.some_func(), resource_2.some_func())

class TestCase1(unittest.TestCase):
    @mock.patch('__main__.ClassToPatch', autospec = True)
    def test_1(self, mock1):
        ctpMocks = [mock.Mock(), mock.Mock()]
        ctpMocks[0].some_func.return_value = "funky"
        ctpMocks[1].some_func.return_value = "monkey"
        mock1.side_effect = ctpMocks

        u = UUT()
        self.assertEqual(u.test_property, ("funky", "monkey"))

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

我已经添加test_property到UUT,以便单元测试做一些有用的事情.现在,没有mock test_property应该是一个包含两个ClassToPatch实例的id的元组.但是有了模拟它应该是元组:("funky", "monkey").

我已经使用了side_effect模拟对象的属性,以便ClassToPatchUUT初始化程序的每次调用中返回不同的实例.

希望这可以帮助.

编辑:哦,顺便说一句,当我运行单元测试时,我得到:

.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK
Run Code Online (Sandbox Code Playgroud)