У меня также было довольно много проблем с испытаниями Xcode 5. Это по-прежнему кажется довольно неудобным с каким-то странным поведением - однако я нашел определенную причину, по которой ваш конкретный XCTAssertEqual
не работает.
Если мы посмотрим на тестовый код, мы видим, что на самом деле делает следующее (взятый непосредственно из XCTestsAssertionsImpl.h
- это может быть проще, чтобы посмотреть там):
#define _XCTPrimitiveAssertEqual(a1, a2, format...) \
({ \
@try { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
float aNaN = NAN; \
NSValue *aNaNencoded = [NSValue value:&aNaN withObjCType:@encode(__typeof__(aNaN))]; \
if ([a1encoded isEqualToValue:aNaNencoded] || [a2encoded isEqualToValue:aNaNencoded] || ![a1encoded isEqualToValue:a2encoded]) { \
_XCTRegisterFailure(_XCTFailureDescription(_XCTAssertion_Equal, 0, @#a1, @#a2, _XCTDescriptionForValue(a1encoded), _XCTDescriptionForValue(a2encoded)),format); \
} \
} \
@catch (id exception) { \
_XCTRegisterFailure(_XCTFailureDescription(_XCTAssertion_Equal, 1, @#a1, @#a2, [exception reason]),format); \
}\
})
Вот проблема:
В самом деле, этот тест кодирует значения в NSValue
, а затем сравнивает их. «Хорошо, - говорите вы, - но в чем проблема?» Я не думал, что есть один, пока я не сделаю свой собственный тест. Проблема заключается в том, что NSValue's -isEqualToValue
также должен сравнить тип кодировки NSValue типа, а также его фактическое значение. Оба метода должны быть равны для возвращаемого метода YES
.
В вашем случае arr.count
является NSUInteger
который является typedef unsigned int
. Постоянная времени компиляции 3
предположительно вырождается в signed int
во время выполнения. Таким образом, когда эти два объекта помещаются в объект NSValue
, их типы кодирования не равны и, следовательно, два CAN NOT не равны в соответствии с -[NSValue isEqualToValue]
.
Вы можете подтвердить это с помощью специального примера. Следующий код явно делает именно то, что делает XCTAssertEqual
:
// Note explicit types
unsigned int a1 = 3;
signed int a2 = 3;
__typeof__(a1) a1value = (a1);
__typeof__(a2) a2value = (a2);
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))];
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))];
if (![a1encoded isEqualToValue:a2encoded]) {
NSLog(@"3 != 3 :(");
}
"3 != 3 :("
появится в журнале каждый раз.
Я спешу добавить здесь, что это, по сути, ожидаемое поведение. NSValue
: Предполагается, что проверяет кодировку своего типа при выполнении сравнений. К сожалению, это просто не то, что мы ожидали при тестировании двух («равных») целых чисел.
XCTAssertTrue
, между прочим, имеет гораздо более простую логику и ведет себя в целом как и ожидалось (опять же, посмотрите на фактический источник того, как он определяет, не выполняется ли утверждение).
Некоторые другие большие библиотеки Сличитель являются: OCHamcrest и Expecta. , есть также Kiwi и Cedar - полноценные тестовые рамки с красивыми встроенными библиотеками-соломерами. , (На всякий случай вы еще не пробовали их). –