2012-05-29 80 views
0

我有一個UUT類,它實例化Worker對象,並調用它們的do_stuff()方法。
Worker對象使用一個Provider對象爲兩件事情:蟒蛇模擬得到調用對象

  1. 提供商對象上的調用方法通過訂閱與提供商的事件的方法做一些東西
  2. 獲取來自供應商的通知

當工作人員得到通知時,它會處理它,通知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產生的作業人員對象,不必直接訪問在uut_workers列表(這是一個實現細節)?

我想我可以在Worker.__init__,那裏的工人訂閱提供商的事件做到這一點,所以我想這個問題簡化爲:主叫resource.default_resource.subscribe('on_spam', self._on_spam)
如何我在被叫提取self,?

+0

你想要什麼是不可能的。如果它不可測試,請更改您的API。 – schlamar

+0

或者你可以修改'Worker'類。 – schlamar

+0

@ ms4py - 我在單元測試階段修補了'Worker'類。現在我正在進行集成測試,並且我希望看到整個堆棧一起工作 – bavaza

回答

-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。而且你也不需要嘲笑資源事物,這使得測試依賴於與被測試類無關的事情。

+0

您可以通過直接修補Worker類來實現此目的。我不會在Python中建議一個工廠函數。 – schlamar

+0

@bereal - 在我的情況下不可能注射 - 請參閱我添加的說明。 – bavaza

+0

@ ms4py這取決於使用的方法。在TDD中,DI總是優於任何修補,因爲(簡而言之)測試不應該意識到實現,所以修補是一種設計氣味。在非TDD ......好吧,作爲一名TDD迷,我不會用一根長棍來觸及那個話題。 – bereal