2014-03-12 138 views
0

我有一個單元測試:比較[class]不起作用?

- (void)testFetchTrackByTrackIdIsATrack 
{ 
    [self addTrackWithSongId:@"123"]; 
    Track *fetchedTrack = [self.library trackByTrackId:@"123"]; 
    assertThat(fetchedTrack, instanceOf([Track class])); 
} 

哪些失敗:

file:///Users/elliot/Development/Hark/HarkTests/TestLibrary.m: test failure: 
-[TestLibrary testFetchTrackByTrackIdIsATrack] failed: Expected an instance 
of Track, but was Track instance <Track: 0x6180001077d0> 

我有使用相同的實例上運行不同類別檢查其他幾個測試 - 但我不能鍛鍊爲什麼這不起作用。鑽研更深:

- (void)testFetchTrackByTrackIdIsATrack 
{ 
    [self addTrackWithSongId:@"123"]; 
    Track *fetchedTrack = [self.library trackByTrackId:@"123"]; 
    Class c1 = [fetchedTrack class]; 
    Class c2 = [Track class]; 
} 

調試器報告:

c1 Class Track   0x0000000100012fe0 
c2 Class 0x1000b3eb8  0x00000001000b3eb8 

注意它是如何看不出[Track class]是一類Track類型的?當我將這個相同的邏輯應用到正在傳遞的其他單元測試時,他們都會報告正確的類名。

感覺它在運行時沒有類元數據,但爲什麼?

一些更多的情況:

assertTrue(c1 == c2);         // FAIL 
assertThat([fetchedTrack classDescription], 
    equalTo([Track classDescription]));     // PASS 
assertTrue([fetchedTrack isKindOfClass:[Track class]]); // FAIL 

回答

5

有任何數量的原因類的地址可能不會隨時間是恆定的,其中大部分可以歸結爲使用鍵 - 值觀察的。

當觀察到一個實例時,運行時(Foundation框架,真的)組成了一個新類,它是包含觀察機制的實例原始類的子類。

這導致無法使用指針比較。這也意味着某些類型的反思該類將無法產生預期的結果。

在短;對所有這些測試使用isKindOfClass:isMemberOfClass:方法,並且使用指針相等性測試(對於這個或者對於通常的比較實例)使用從來沒有

+0

參考:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOImplementation.html – vikingosegundo

+1

自動鍵值觀察是使用稱爲isa-swizzling的技術實現的。 顧名思義,isa指針指向維護調度表的對象的類。這個調度表實質上包含指向該類實現的方法的指針以及其他數據。 當一個觀察者註冊一個對象的屬性時,觀察對象的isa指針被修改,指向一箇中間類而不是真實類。結果isa指針的值不一定反映實例的實際類。 – vikingosegundo

+0

OCHamcrest中的'instanceOf()'匹配器使用'isKindOfClass:'。我已經將明確的測試添加到了我的原始帖子中,以顯示它仍然不起作用... –