0

我有一个单元测试:

- (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
4

1 回答 1

5

类的地址随着时间的推移可能不会保持不变的原因有很多,其中大多数归结为使用键值观察。

当观察到一个实例时,运行时(实际上是 Foundation 框架)组成一个新类,它是包含观察机制的实例原始类的子类。

这导致无法使用指针比较。这也意味着某些类型的类内省将无法产生预期的结果。

简而言之; 对所有此类测试使用isKindOfClass:andisMemberOfClass:方法,并且从不使用指针相等测试(通常用于此或用于比较实例)。

于 2014-03-12T21:56:02.170 回答