Ser*_*gey 37 objective-c ocunit xctest
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.");
Run Code Online (Sandbox Code Playgroud)
我对XCTAssertEqual不了解什么?为什么最后一个断言失败了?
Eph*_*era 47
我对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); \
}\
})
Run Code Online (Sandbox Code Playgroud)
这是问题所在:
测试实际上做的是将值编码为a NSValue然后进行比较."好的,"你说,"但那有什么问题?" 在我为自己制作测试用例之前,我认为没有一个.问题是NSValue -isEqualToValue还必须比较NSValue的编码类型及其实际值.对于返回的方法,两者必须相等YES.
对你来说,arr.count是一个NSUInteger这是一个typedef unsigned int.编译时常量3可能会signed int在运行时退化为a .因此,当两者被放入一个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 :(");
}
Run Code Online (Sandbox Code Playgroud)
"3 != 3 :(" 每次都会出现在日志中.
我赶紧在这里补充一点,事实上,这是预期的行为.NSValue是应该做比较时,检查它的类型编码.不幸的是,这不是我们在测试两个('相等')整数时所期望的.
XCTAssertTrue顺便提一下,它具有更直接的逻辑,并且通常表现得如预期的那样(再次,看看它如何确定断言是否失败的实际来源).
我也遇到过这个问题.正如@ephemera和@napier所说,这是一个类型问题.
它可以通过使用c-literal修饰符提供正确类型的值来解决.
XCTAssertEqual(arr.count, 3ul, @"Wrong array size.");
Run Code Online (Sandbox Code Playgroud)
您可以通过查找左侧使用的函数的返回类型找到正确的类型 - ALT-click在arr上.count:
- (NSUInteger)count;
Run Code Online (Sandbox Code Playgroud)
现在ALT-单击NSUInteger以查找其类型:
typedef unsigned long NSUInteger;
Run Code Online (Sandbox Code Playgroud)
现在找到unsigned long的c文字数字格式 - 谷歌是一个好朋友,但这个页面有效:
http://www.tutorialspoint.com/cprogramming/c_constants.htm
作为这里的快速提示,您可能需要使用U(无符号)L(长整数)或F(浮点数),并确保编写1.0而不是1来获得双精度.小写也可以,如上例所示.
| 归档时间: |
|
| 查看次数: |
16583 次 |
| 最近记录: |