2013-09-26 55 views
2

我正在使用XCTest和OCMock 2.2.1進行單元測試。我有一個類,其獲得使用束標識:在部分模擬對象上調用+ [NSBundle bundleForClass:]返回的結果與unmocked對象不同?

NSString *bundleIdentifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier]; 

這按預期工作在運行應用程序或用於此類特別是單元測試。

在對其他類進行測試時,我部分地嘲笑了這個對象,但仍需要獲取包標識符才能運行的方法。

前傳遞對象的實例+ [OCMockObject partialMockForObject:]我所看到的是看起來是正確的:

(lldb) po myObject 
<MyObject: 0x1006ec480> 
(lldb) po [NSBundle bundleForClass:[myObject class]] 
NSBundle </Users/paynerc/Library/Developer/Xcode/DerivedData/xxxx/Build/Products/Debug/MyTests Tests.xctest> (loaded) 
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier] 
com.paynerc.MyBundle 

但是,我通過後myObject[OCMockObject partialMockForObject:myObject],事情的變化:

(lldb) po myObject 
<MyObject-0x1006ec480-401894396.880136: 0x1006ec480> 
(lldb) po [NSBundle bundleForClass:[myObject class]] 
NSBundle </Applications/Xcode.app/Contents/Developer/usr/bin> (loaded) 
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier] 
nil 

事實該對象被修改幷包含部分模擬魔術是有意義的。似乎沒有道理的是爲什麼對bundleForClass的呼叫改變了它返回的內容。

有什麼我可以做的,以確保bundleForClass繼續返回原始值,嘲笑MyObject內的調用嗎?我們擔心的是,在另一個單元測試中需要對MyObject進行部分模擬的其他人需要記得提供bundleForClass的存根實現。

我現在的解決方案是請求包標識符並檢查結果。如果它是零,我打電話[NSBundle allBundles]並迭代他們,直到我找到一個具有非零的bundleIdentifier。雖然目前... 工程 ...這是A)不是非常強大的B)可怕的蠻力 - ish和C)修改應用程序代碼以支持單元測試。

有沒有人遇到過這個問題,想出一個更好的解決方案?

回答

3

運行時運行正常。模擬對象是NSProxy的一個子類,因此對象的isa與該包之間的運行時間綁定被有效破解(特別是,isa指向Class,然後通過dyld API查找該運行時綁定以確定機器映像它是從加載的,用於查找捆綁)。

OCMockObject代理(或子類OCPartialMockObject)可能允許您檢索原始類。當然,你必須使用這些,這意味着你將會用模擬調用來污染你的代碼,而這些調用只應該用在測試中。

或者,在你的bundle/framework /類的其中一個類上實現一個類方法,不管它返回該類的包。這不應該被嘲笑。

+0

比爾和平常一樣。但是,我們正在改變模擬對象的行爲,以便它能夠滿足您的期望。這是正在進行中的工作。請參閱https://github.com/erikdoe/ocmock/pull/45和https://github.com/erikdoe/ocmock/commit/c7ed21cead25a78c98fd46e1f95defef4721e5e6 –

+0

NSProxy子類通常實現-isKindOfClass:爲代理的類返回YES,和OCClassMockObject沒有什麼不同。(儘管它也許應該實現--class,因爲NSProxy子類通常也會這樣做)。但是這裏的問題在於原始對象被自己嘲笑 - 部分模擬過程改變了它的「isa」指針,因此來自-class方法的返回值是不同的,這反過來弄亂了bundleForClass :.但正如Erik所說,它看起來應該在下一個版本的OCMock中得到解決。 –

+0

@CarlLindberg感謝您的澄清;我之前沒有看過OCMock *的實現。 – bbum