Подтвердить что ты не робот

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

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

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

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

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

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

  • Установите "Загрузочный загрузчик" на $(BUILT_PRODUCTS_DIR)/AppName.app/AppName

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

target 'MyProject' do
pod 'Parse'

end

target 'MyProjectTests' do

end

target 'MyProjectUITests' do

end

Ответ 3

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

Target Membership

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

Target Membership
[X] Foo
[ ] FooTests

Ответ 4

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

Ответ 5

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

Решение:

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