Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен

Недавно я начал модульное тестирование своего приложения. Этот проект (в Xcode4) был создан без единого тестового пакета, поэтому мне пришлось его настроить. Я выполнил следующие шаги: http://cocoawithlove.com/2009/12/sample-mac-application-with-complete.html И он хорошо работал для простых classов, но теперь я пытаюсь проверить class, который зависит на другом, а на другом и т. д.

Сначала у меня появилась ошибка компоновщика, поэтому я добавил файлы *.m в целевой тестовый пример, но теперь я получаю предупреждение для каждого classа, который я пытаюсь проверить:

Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен.

Интересно, почему? Как я могу это решить? Может быть, я что-то пропустил, установив цель тестирования?

Изменить – решение

  • Установите «Bundle Loader» правильно на $(BUILT_PRODUCTS_DIR)/AppName.app/AppName

  • Установите «Символы, скрытые по умолчанию», на « НЕТ» (в настройках сборки целевого приложения). Здесь возникают ошибки компоновщика, поскольку по умолчанию это ДА !. Я так долго боролся с этим!

Источник: ошибка связи для модульного тестирования с XCode 4?

Класс Foo реализован как в MyApp, так и в MyAppTestCase. Один из двух будет использован. Какой из них не определен.

Интересно, почему?

потому что оба изображения (приложение и единичный тестовый комплект) определяют реализацию classа. class динамически загружается в среду выполнения objc. во время выполнения objc используется плоское пространство имен. как это работает:

  • бинарный файл загружается, начиная с его зависимостей
  • поскольку каждый двоичный файл загружается, classы objc регистрируются в среде выполнения objc
  • если class с определенным именем загружается дважды, поведение не определено. одна реализация classа (с идентичными именами) может быть загружена в среду выполнения objc.

типичная проблема здесь в том, что вам будет возвращена одна реализация – ваше приложение, скорее всего, сработает, когда конфликт типа (когда class не приходит из одного и того же исходного файла).

вы обычно избегаете этого, переименовывая class или экспортируя class в одно изображение. переименование classа, очевидно, не относится к вашему делу. у вас есть один файл Foo.m который компилируется, экспортируется и загружается двумя изображениями, когда он должен быть в одном.

это должно интерпретироваться вами как ошибка дубликата символьного символа. хотя реализация является одним и тем же исходным файлом (и реализация такая же) – это проблема, которую вы должны исправить.

Как я могу это решить?

если Foo.m является classом приложения, вы должны удалить (не компилировать и не связывать) Foo.m из модульного теста. если это часть модульного теста, то не компилируйте и не связывайте его с целевой тестовой единицей.

затем следуйте инструкциям в сообщении для связывания / загрузки вашего модульного теста в приложение. он находится в этой общей области сообщения: где «WhereIsMyMac» – это название приложения, которое вы тестируете на модуле. Это позволит целевой целевой среде тестировать приложение (поэтому при компиляции вы не получите ошибок компоновщика). важная часть заключается в том, что ваши тестовые файлы скомпилированы в целевой тестовой единице (только), а classы вашего приложения скомпилированы и связаны в приложении. вы не можете просто добавить их – они связываются и загружаются динамически.

Может быть, я что-то пропустил, установив цель тестирования?

Из статьи, которую вы указали:

Примечание. objective тестирования – отдельная цель. Это означает, что вам нужно быть осторожным с целевым членством. Все исходные файлы приложений должны быть добавлены только к целевой программе. Файлы тестового кода должны быть добавлены только к цели тестирования.

часть, в которой вы ошибаетесь, вероятно, является фазой связи и нагрузки модульного тестового комплекта.

Если вы используете Cocoapods, ваш файл подкачки нуждается только в зависимостях в разделе главной цели, а не в тестовых целях. Если вы добавляете повторяющиеся зависимости для целевых объектов, вы получите сообщение об ошибке OP.

 target 'MyProject' do pod 'Parse' end target 'MyProjectTests' do end target 'MyProjectUITests' do end 

Для меня все, что мне нужно было сделать, это снять флажок, который делает class Foo членом целевой тестовой единицы. Он не должен быть членом обеих целей и должен выглядеть следующим образом:

Целевое членство

Если вы не видите изображение, это снимок экрана панели «Целевое членство» Xcode. Есть две цели: одна с иконкой приложения «А» и именем теста. Другая – целевая единица измерения единицы измерения и имеет идентификатор тестовой единицы:

 Target Membership [X] Foo [ ] FooTests 

Для меня это произошло потому, что я развернулся к устройству, а затем к симулятору, так как у меня есть NSZombies. Решение состояло в том, чтобы переключиться на конфигурацию тренажера и выполнить Product -> Clean, затем переключиться на конфигурацию устройства и сделать то же самое. Ошибка исчезла. Это связано с построением кеша.

Причина в том, что вы переопределяете RUNPATH_SEARCH_PATHS настройки RUNPATH_SEARCH_PATHS App Target, определенной в другой целевой.

Решение:

Перейдите в свою App Target и найдите настройку RUNPATH_SEARCH_PATHS и используйте там флаг $(inherited) для обоих: Debug и Release

Перейдем к тем же проблемам. Моей ситуацией является class NSNotification реализуется как в /System/Library/Frameworks/Foundation.framework/Foundation, есть ли какие-либо чуваки, сталкивающиеся с одной и той же проблемой, будут направлены какие-либо направления или рекомендации.

  • запись NSDictionary для plist в моем приложении
  • На iPhone: узнать, какая песня сейчас играет? (в музыкальном проигрывателе iPod)
  • Очереди отправки: как узнать, запущены ли они и как их остановить
  • Как сделать ui отзывчивым все время и делать обновление фона?
  • Должен ли я использовать NSUserDefaults или plist для хранения данных?
  • Держите iphone активным во время запуска программы
  • Разбор даты JSON на IPhone
  • Координаты текстуры OpenGL в пиксельном пространстве
  • UISwitch в ячейке UITableView
  • UITableViewCell расширяется по клику
  • Лучший способ сохранить данные на iPhone
  • Interesting Posts
    Давайте будем гением компьютера.