2013-03-24 2 views
4

Каков правильный способ подсчета количества элементов NSArray с помощью STAssertEquals для NSArray.STAssertEquals для проверки количества 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?

UPDATE 1

Спасибо за ответы предложил использовать 1u, как беззнаковое INT буквальным

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

Но, как упоминалось @Aaron это еще некрасиво - я хотел бы использовать "1" прямо - думая об использовании myArray.count == 1 вместо этого сейчас. И причина этого в том, что 1u не выглядит очень чистым. 1 для меня 1. Вы никогда не пишете 1u в математике :-) Любые другие предложения?

UPDATE 2

Как @ H2CO3 упоминались 1u даже не всегда может работать и как предложено в какой-то теме мы могли бы использовать более декларативное определение ожидаемого значения, которое позволит решить проблему литья:

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

Я предпочитаю его 1u-решение, потому что он выглядит чище. Но минусы этого подхода состоят в том, что у нас есть дополнительная строка и код не очень компактный. Итак, похоже, нам нужно выбирать между двумя подходами: (NSUInteger)1 и NSUInteger expectedItemsCount = 1;

+0

Интересно, это означает, что вы включили флаг 'CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION', сделали ли вы это (или кто-то из проекта) или обновили последнее обновление Xcode? Я думал, что это по умолчанию. – Pascal

+0

@Pascal OP не получает предупреждение о компиляторе - он получает ошибку ** runtime **. – 2013-03-24 15:54:10

+0

@ H2CO3 О, святой ...! – Pascal

ответ

4

система типа C в ...

1 является int, поэтому он подписал. NSArray.count - NSUInteger, поэтому он неподписан. Сделайте целое число буквальным без знака:

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

Edit: Даже лучше, выше, будет не в состоянии на 64-битной (он будет работать с 1ull там), так что, если вы просто использовать что-то вроде

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

(The thread from where I stole this...)

+0

Вторая версия для меня немного перевернута, я бы просто бросил вещь. – Pascal

+0

@Pascal Это лучше, чем литье. (В C все лучше, чем литье.) – 2013-03-24 15:56:04

+0

Также для литералов? Я предположил, что в этих случаях он подскажет компилятору, что делать, чтобы он использовал правильные типы. – Pascal

1

Вы можете использовать STAssertEquals(1U, myArray.count, @"One item should be in array");, чтобы сделать 1 без знака. Может быть, это все еще некрасиво. Это немного меньше печатает.

1

1U верен.Но если вы хотите, чтобы избежать этого безобразия (и шага в лучший мир утверждений), используйте OCHamcrest:

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

спасибо за ответ. Что это? Hamcrest? Я не хочу использовать дополнительную библиотеку здесь и вместо этого использовать стандартные инструменты. Также hasCountOf выглядит довольно странно, если вы хотите сравнить два значения.Я никогда не видел такого подхода в других языках, таких как Ruby или Java. Но спасибо за то, что указали, что это - хорошо знать все возможные решения. – Vladimir

+0

Hamcrest родился в Java и теперь является стандартной частью JUnit. –

+0

спасибо, что упомянул об этом, - я не пытался использовать его даже в Java. Посмотрим! – Vladimir

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==...) 

и теперь ваши тесты блок проверки достоверности объекта, тоже.

+0

Привет @MarkBernstein. Я думаю, что это добавляет дополнительную сложность для создания специального макроса для проверки количества массивов. Мы будем использовать операции, которые у нас уже есть, а не определять нашу собственную математику :-) – Vladimir

+0

Конечно, если вы делаете это только иногда, вам не нужен ваш собственный макрос! Но в целом это очень полезный метод. Для получения дополнительной информации см. Книгу Мезароса по xUnit Test Patterns. –

0

Как я сделать это, чтобы сравнить их как объекты, которые будут работать на 32 & 64 бит, предотвратить необходимость любого литья или ненужных объявления переменных, а также поддерживать хорошее сообщение об ошибке, которое включает неудачное значение:

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

 Смежные вопросы

  • Нет связанных вопросов^_^