代码之家  ›  专栏  ›  技术社区  ›  David Parks

如何模拟多处理.Event.is_set()-AttributeError

  •  0
  • David Parks  · 技术社区  · 5 年前

    我是在嘲笑一个女人 multiprocessing.Event 对象,以便调用 event.is_set() 第一次迭代返回False,第二次迭代返回true。我在以下尝试中失败:

    import unittest
    import unittest.mock as mock
    import multiprocessing
    
    
    class MyClassUnderTest:
        def __init__(self):
            self.event = multiprocessing.Event()
            # start a Process which immediately uses self.event
    
        def my_method_under_test(self):
            while not self.event.is_set():
                pass  # do something
            return True
    
    
    class TestMyClassUnderTest(unittest.TestCase):
        @mock.patch.object(multiprocessing.Event, 'is_set', return_value=False)
        def test_my_method(self, mock_event):
            mock_event.side_effect = [False, True]
    
            myobj = MyClassUnderTest()
            self.assertTrue(myobj.my_method_under_test())
    

    我最后得到了一个错误:

    AttributeError: <bound method BaseContext.Event of <multiprocessing.context.DefaultContext object at 0x7f1068a50e48>> does not have the attribute 'is_set'
    

    我不能推翻 MyClassUnderTest.event 多处理事件

    0 回复  |  直到 5 年前
        1
  •  1
  •   Fanchen Bao    4 年前

    为了响应@David Parks的号召,这里有一个简化的工作示例。

    import unittest
    import unittest.mock as mock
    import multiprocessing
    
    
    class MyClassUnderTest:
        def __init__(self):
            self.event = multiprocessing.Event()
            # start a Process which immediately uses self.event
    
        def my_method_under_test(self):
            while not self.event.is_set():
                pass  # do something
            return True
    
    
    class TestMyClassUnderTest(unittest.TestCase):
        @mock.patch('multiprocessing.Event')
        def test_my_method(self, mock_event):
            mock_event.is_set.side_effect = [False, True]
    
            myobj = MyClassUnderTest()
            self.assertTrue(myobj.my_method_under_test())
    

    诀窍是修补问题 Event is_set() 在测试机构中。老实说,我不知道为什么我们不能直接修补 multiprocessing.Event.is_set ,鉴于 multiprocessing.Event 是一个克隆的 threading.Event .

        2
  •  1
  •   David Parks    5 年前

    这里有一个方法可以用 configure_mock :

    import unittest
    import unittest.mock as mock
    import multiprocessing
    
    
    class MyClassUnderTest:
        def __init__(self):
            self.event = multiprocessing.Event()
            # start a Process which immediately uses self.event
    
        def my_method_under_test(self):
            while not self.event.is_set():
                pass  # do something
            return True
    
    
    class TestMyClassUnderTest(unittest.TestCase):
        @mock.patch('multiprocessing.Event')
        def test_my_method(self, mock_event):
            mock_event.configure_mock(**{'is_set.side_effect': [False, True]})
    
            myobj = MyClassUnderTest()
            self.assertTrue(myobj.my_method_under_test())
    

    如果有人知道如何把这完全浓缩成 @mock.patch(...) 这仍然是有用的。