使用STAsertEquals为NSArray检查NSArray项目计数的正确方法是什么。
预计会有以下工作:
...
STAssertEquals(1, [myArray count], @"One item should be in array");
此代码在运行测试时会产生“类型不匹配”运行时错误。
相反,我必须对NSUInteger进行显式转换:
STAssertEquals((NSUInteger)1, [myArray count], @"One item should be in array");
这是有效的 - 但由于明确的演员而看起来很丑陋。
我还想避免使用STAssertTrue,因为STAssertEquals看起来更合适(我们比较两个值)并显示实际值和期望值。
在Objective-C中检查它的正确方法是什么?
更新1
感谢您建议使用1u作为unsigned int literal
的答案STAssertEquals(1u, [myArray count], @"One item should be in array");
但是@Aaron提到它仍然很难看 - 我想直接使用“1” - 现在考虑使用myArray.count == 1。原因是1u看起来不太干净。 1对我来说是1。你永远不会在数学中写1u :-)还有其他任何建议吗?
更新2
由于@ H2CO3提到1u甚至不能总是工作,并且正如在某些线程中所建议的那样,我们可以使用更多的声明性定义来预期值,这将解决转换问题:
NSUInteger expectedItemsCount = 1;
STAssertEquals(expectedItemsCount, [myArray count], @"One item should be in array");
我更喜欢1u解决方案,因为它看起来更干净。但这种方法的缺点是我们有额外的行和代码不是很紧凑。因此,我们必须在两种方法之间进行选择:(NSUInteger)1
和NSUInteger expectedItemsCount = 1;
答案 0 :(得分:4)
C的类型系统......
1
是int
,因此已签名。 NSArray.count
为NSUInteger
,因此未签名。使整数文字无符号:
STAssertEquals(myArray.count, 1u, @"+1 item needed");
编辑:更好的是,上面的内容将在64位上失败(它可以与1ull
一起使用),那么如果您只是使用
const NSUInteger expectedLength = 1;
STAssertEquals(myArray.count, expectedLength, @"+1 item needed");
答案 1 :(得分:1)
您可以使用STAssertEquals(1U, myArray.count, @"One item should be in array");
使1无符号。也许这仍然是丑陋的。打字少了一点。
答案 2 :(得分:1)
1U是正确的。但如果你想避免这种丑陋(并进入更好的断言世界),请使用OCHamcrest:
assertThat(myArray, hasCountOf(1));
答案 3 :(得分:0)
如果您的项目很重要,或者您希望此代码具有较长的使用寿命,请考虑为此类事件添加特定的断言。定义一个特殊情况宏
STArrayCount(myArray,1)
可以扩展到像
这样的东西 STAssertTrue(myArray.count==1u,@"Expected %u but array count is %u",myArray.count,1);
编写自定义断言使您的单元测试在几年内重新访问时更加清晰,并且还为其他测试提供了一个钩子。假设今天myArray是一个NSArray,但不久之后它变成了BigFancyObject的一个实例,它做了一些其他事情。 BigFancyObjects使您的大部分代码更加清晰,并隐藏实现细节,所以这一切都很棒。但是你想确定BigFancyObject是有效的,因为有些东西会让它们无效。因此,您可以将STArrayCount重新定义为
STAssertTrue(myArray.isValid && myArray.count==...)
现在你的单元测试也会检查对象的有效性。
答案 4 :(得分:0)
我这样做的方法是将它们作为对象进行比较,这将在32& 64位,防止需要任何强制转换或不必要的变量声明,并维护一个包含失败值的错误消息:
STAssertEqualObjects(@(5), @(datas.count), @"unexpected array count");