python mock获取调用对象

时间:2012-05-29 13:58:30

标签: python mocking patch

我有一个UUT类来实例化Worker个对象,并调用他们的do_stuff()方法。
Worker个对象使用Provider对象进行两件事:

  1. 调用提供者对象上的方法来做一些事情
  2. 通过使用提供商的活动
  3. 订阅方法,从提供商处获取通知

    当工作人员收到通知时,它会对其进行处理,并通知UUT对象,在响应中可以创建更多Worker个对象。

    我已经自己测试了每个课程,我想一起测试UUT + Worker。为此,我打算嘲笑Provider

    import mock
    import unittest
    import provider
    
    class Worker():
        def __init__(self, *args):
            resource.default_resource.subscribe('on_spam', self._on_spam) # I'm going to patch 'resource.default_resource'
    
        def do_stuff(self):
            self.resource.do_stuff()
    
        def _on_spam(self, message):
            self._tell_uut_to_create_more_workers(message['num_of_new_workers_to_create'])
    
    
    class UUT():
        def __init__(self, *args):
            self._workers = []
    
        def gen_worker_and_do_stuff(self, *args)
           worker = Worker(*args)
           self._workers.append(resource)
           worker.do_stuff()
    
    
    class TestCase1(unittest.TestCase):
    
        @mock.patch('resource.default_resource', spec_set=resource.Resource)
        def test_1(self, mock_resource):
            uut = UUT()
            uut.gen_worker_and_do_stuff('Egg')   # <-- say I automagically grabbed the resulting Worker into self.workers
            self.workers[0]._on_spam({'num_of_new_workers_to_create':5}) # <-- I also want to get hold of the newly-created workers
    

    有没有办法获取uut生成的工作对象,而不直接访问_workers中的uut列表(这是一个实现细节)?

    我想我可以在Worker.__init__中执行此操作,其中工作者订阅提供者事件,因此我想这个问题简化为:
    如何在调用self

    时提取被叫方中的resource.default_resource.subscribe('on_spam', self._on_spam)

1 个答案:

答案 0 :(得分:-1)

作为依赖倒置原则的应用,我将Worker类作为依赖项传递给UUT

class UUT():
    def __init__(self, make_worker=Worker):
        self._workers = []
        self._make_worker = make_worker

    def gen_worker_and_connect(self, *args)
       worker = self._make_worker(*args)
       self._workers.append(resource)
       worker.connect()           

然后从测试中提供您想要的任何内容,而不是Worker。这个自己的函数可以与测试范围共享创建的对象。除了解决这个特定的问题,这也会使依赖显式并独立于UUT实现。而且你也不需要模拟资源,这使得测试依赖于与被测试类无关的事情。