2014-01-24 20 views
4

我想單元測試一個作爲CBPeripheralManagerDelegateCBPeripheralManager類的類。通常情況下,爲了去掉外部類的依賴關係,我可以通過類初始化程序或通過屬性傳遞依賴注入的形式。在處理基於單例的API時,我能夠使用像Kiwi這樣的庫來存儲返回單例的類級方法(即[ClassName stub:@selector(sharedInstance) andReturn:myStubbedInstance])。在嘲諷CBPeripheralManager的情況下,問題是它的初始化程序需要委託實例。因此,使用我的類的任何代碼都需要做這樣的事情:一個單元如何測試與核心藍牙API交互的代碼?

PeripheralManagerWrapper *wrapper = [[PeripheralManagerWrapper alloc] init]; 
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:wrapper queue:nil options:nil]; 
wrapper.peripheralManager = peripheralManager; 

然後,單元測試我PeripheralManagerWrapper類,我可以簡單地將它實例化,並通過在嘲笑CBPeripheralManager。但是,我不喜歡要求我的包裝對象的任何調用代碼必須通過此設置。處理這種情況是否有更好的模式?我已經使用了Kiwi和OCMockito,但似乎都沒有提供這種功能,因爲它們可能不會提供CBPeripheralManagerallocinit方法的存根,然後只是在PeripheralManagerWrapper 的初始化程序中實例化實例。

回答

4

恕我直言,核心藍牙API是完美匹配的單元測試。所有委託回調都需要經理和相關參數,所以如果您遵循使用這些參數而不是內部狀態的模式,那麼您將能夠傳入任何您想要的內容。使用模擬對象是做到這一點的最佳方式。在單元測試的時候,你不應該試圖嘲笑經理的行爲。您應該專注於驗證代碼與API的交互,而不再僅限於此。

包裝可能更適合集成測試。但實際上,核心藍牙代碼的集成測試更好地根據我的經驗手動完成。該堆棧不夠穩定,無法進行可靠的測試,並且測試代碼也必須強化堆棧錯誤,這實際上很難,因爲很明顯,僅通過查看API就無法記錄或預測堆棧錯誤。另一方面,您的測試代碼也必須模擬堆棧的錯誤行爲。有時可能會有這種情況,但如果測試代碼不超過您正在測試的代碼,測試代碼將會同樣複雜。

+0

是的,包裝並不是真正的測試,而是更多的隔離遠離ViewController的藍牙行爲。包裝可能不是最好的後綴。 –

+0

好。將業務邏輯與第三方API分開始終是一種很好的做法。我有回答你的問題嗎? – allprog

+0

是的,很抱歉沒有將它標記爲這樣! –