Модульное тестирование iPhone: символы не обнаруживаются при вызове пользовательского кода

Я пытаюсь настроить модульное тестирование для своего приложения для iPhone. Я следил за Документация по модульному тестированию Apple, и это подействовало нормально, но как только я добавил в этот тест еще один класс, я получил следующую ошибку:

  "_OBJC_CLASS_$_RootViewController", referenced from:
      __objc_classrefs__DATA@0 in AppDelegateTests.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Само приложение представляет собой базовое навигационное приложение с базовыми данными для хранения данных.

Модульный тест выглядит следующим образом:

#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

#import "HSStabilityAppAppDelegate.h"
#import "RootViewController.h"
@interface AppDelegateTests : SenTestCase {
 HSStabilityAppAppDelegate *appDelegate;
}
@end


@implementation AppDelegateTests
// all code under test must be linked into the Unit Test bundle


#pragma mark -
#pragma mark Set up and tearDown

#if APPLICATION_TESTS
- (void) setUp {
 appDelegate = (HSStabilityAppAppDelegate *)[[UIApplication sharedApplication] delegate];
 STAssertNotNil(appDelegate, @"Cannot find the application delegate.");
}

- (void) tearDown {
 [appDelegate release];
}

#else

#endif


#pragma mark -
#pragma mark Tests

#if APPLICATION_TESTS

- (void) testRootViewIsOnTop {
 id topViewControllerClass = [[appDelegate.navigationController topViewController] class];
 id rootViewControllerClass = [RootViewController class];
 STAssertEquals(topViewControllerClass, rootViewControllerClass, @"Root view controller was not the top class");
}

#endif

@end

Если я закомментирую строку id rootViewControllerClass, тогда программа будет правильно связываться. Кроме того, это происходит только при построении против целевого устройства, у меня нет проблем при построении против симулятора (вероятно, учитывая, что тесты приложений не работают на симуляторе).

Может ли кто-нибудь помочь решить эту простую и очень раздражающую проблему?


person Steve Workman    schedule 06.01.2010    source источник


Ответы (2)


Я также подписался на Apple iPhone Unit Testing Applications и обнаружил ошибку связывания, аналогичную описанной в вопросе, при попытке выполнить модульное тестирование одного из моих классов.

Похоже, что любой класс, на который есть ссылка в вашем классе модульного теста, и поэтому запускаемый из вашей тестовой цели также должен быть добавлен к этой тестовой цели. Для этого щелкните правой кнопкой мыши свой RootViewController класс и выберите «Получить информацию» (ярлык Cmd-i). На панели целей убедитесь, что ваша цель модульного теста (например, «LogicTests», если вы следовали именованию в этом документе) отмечена.

Теперь этот класс будет скомпилирован с вашими тестами и должен быть доступен для вашего модульного теста. Чтобы дважды проверить, разверните узел «Targets / LogicTests / Compile Resources» в браузере «Группы и файлы» слева. В нем перечислены все файлы классов, доступные при построении цели, и теперь они должны включать ваш класс модульного тестирования вместе с тестируемым классом.

(Обратите внимание, что вам нужно будет аналогичным образом выбрать все подходящие цели при создании нового приложения или тестового класса - на той же странице окна «Новый файл ...», когда вы называете файл).

(Я, кстати, использую XCode 3.2.3 и OS 4.0).

person Martin Dow    schedule 15.07.2010

Думаю, я нашел ответ. Проблема в том, что, хотя компилятор может видеть определения, он не смотрит в нужное место при их связывании и поэтому выдает эти ошибки. Следовательно, если мы переместим разрешение имени класса во время выполнения, мы сможем все это обойти.

Вместо: NSManagedObject используйте: NSClassFromString("@NSManagedObject")

Это касается практически всех классов, определенных внутри.

Если кто-нибудь может сказать мне, как заставить его работать во время компиляции, я все равно был бы очень благодарен.

person Steve Workman    schedule 08.01.2010
comment
Вам необходимо убедиться, что исходный код для добавленного вами класса включен в вашу тестовую цель. В разделе «Цели› {your_test_target} ›Compile Sources» вы должны увидеть реализацию вашего класса. Например. если у вас есть #import MyClass.h, убедитесь, что у вас есть MyClass.m в разделе Источники компиляции для вашей тестовой цели. - person Ronnie Liew; 16.03.2010