STAssertEquals to check the number of NSArray - a clean way

What is the correct way to check the number of NSArray elements using STAssertEquals for NSArray.

The following work is expected:

... STAssertEquals(1, [myArray count], @"One item should be in array"); 

This code generates a "Type of mismatch" runtime error when running the test.

Instead, I have to do an explicit cast to NSUInteger:

 STAssertEquals((NSUInteger)1, [myArray count], @"One item should be in array"); 

It works - but it looks clearly ugly due to an explicit cast.

I also want to avoid using STAssertTrue, because STAssertEquals looks more appropriate (we compare two values) and show the actual and expected values.

What is the correct way to test it in Objective-C?

UPDATE 1

Thanks for the answers suggested using 1u as unsigned int literal

 STAssertEquals(1u, [myArray count], @"One item should be in array"); 

But since @Aaron mentioned that it is still ugly - I would like to use "1" directly - now instead of using myArray.count == 1. And the reason for this is that 1u does not look very clean. 1 for me 1. You never write 1u in math :-) Any other suggestions?

UPDATE 2

As mentioned in @ H2CO3, 1u may not always work, and, as suggested in some thread, we could use a more declarative definition of the expected value that would solve the casting problem:

 NSUInteger expectedItemsCount = 1; STAssertEquals(expectedItemsCount, [myArray count], @"One item should be in array"); 

I prefer it for 1u solution because it looks cleaner. But the disadvantages of this approach are that we have an extra line and the code is not very compact. So, it looks like we need to choose between two approaches: (NSUInteger)1 and NSUInteger expectedItemsCount = 1;

+4
source share
5 answers

Type C system ...

1 int , so it is signed. NSArray.count is equal to NSUInteger , so it is unsigned. Make unsigned integer literal:

 STAssertEquals(myArray.count, 1u, @"+1 item needed"); 

Edit: Even better, the 64-bit will not be executed above (this will work with 1ull there), so if you just use something like

 const NSUInteger expectedLength = 1; STAssertEquals(myArray.count, expectedLength, @"+1 item needed"); 

(the thread I stole it from ...)

+4
source

You can use STAssertEquals(1U, myArray.count, @"One item should be in array"); to make 1 unsigned. Maybe it's still ugly. It prints a little less.

+1
source

1U is correct. But if you want to avoid this ugliness (and go to a better world of claims), use OCHamcrest:

 assertThat(myArray, hasCountOf(1)); 
+1
source

If your project is significant or you expect this code to have a long life, consider adding specific statements for such things. Define a special case macro

  STArrayCount(myArray,1) 

which can expand to something like

  STAssertTrue(myArray.count==1u,@"Expected %u but array count is %u",myArray.count,1); 

Entering custom statements makes your unit test clearer when you review it after a few years, and also provides a hook for additional testing. Suppose today myArray is an NSArray, but after a while it will become an instance of BigFancyObject, which performs some other functions. BigFancyObjects makes much of your code much cleaner and hides implementation details, so everything is fine. But you want to be sure that the BigFancyObject is valid because something makes them invalid. So you can override STArrayCount in

  STAssertTrue(myArray.isValid && myArray.count==...) 

and now your unit tests also check the validity of the object.

0
source

The way I do this is to compare them as objects that will work on 32 and 64 bits, prevent the need for any castings or unnecessary variable declarations, and maintain a good error message that includes bad values:

 STAssertEqualObjects(@(5), @(datas.count), @"unexpected array count"); 
0
source

All Articles