NSMutableArray *arr = [NSMutableArray array];
[arr addObject:@"1"];
[arr addObject:@"2"];
[arr addObject:@"3"];

// This statement is fine.
XCTAssertTrue(arr.count == 3, @"Wrong array size.");

// This assertion fails with an error: ((arr.count) equal to (3)) failed: ("3") is not equal to ("3")
XCTAssertEqual(arr.count, 3, @"Wrong array size.");

我对XCTAssertEqual不了解?为什么最后一个断言失败?

最佳答案

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的-isEqualToValue还必须比较NSValue的编码类型及其实际值。两者必须相等才能使方法返回YES

在您的情况下,arr.countNSUInteger,它是unsigned int的类型定义。编译时常量3大概在运行时退化为signed int。因此,当将两者放入NSValue对象时,它们的编码类型不相等,因此根据-[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顺便说一句,它具有更简单的逻辑,并且通常按预期方式运行(再次,请参见实际来源,了解如何确定断言是否失败)。

关于objective-c - XCTAssertEqual错误:(“3”)不等于(“3”),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19178109/

10-11 14:48