65

My unittest target build failed with below error:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_MCStore", referenced from:
      objc-class-ref in MCStoreTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Basic information:

  • Xcode6.2
  • iOS8.2 SDK

What I have checked:

  • Symbols Hidden by Default is No
  • Other Linker Flags is -framework XCTest
  • Framework Search Paths is $(SDKROOT)/Developer/Library/Frameworks $(inherited)
Cœur
  • 37,241
  • 25
  • 195
  • 267
Yuwen Yan
  • 4,777
  • 10
  • 33
  • 63

14 Answers14

150

According to this link, I need to set Bundle Loader with below content in unittest target Build Settings

$(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingApp

Yuwen Yan
  • 4,777
  • 10
  • 33
  • 63
  • 7
    This answer is a life-saver dude!!! I am so happy I have stumbled upon it!!! So many thanks!!! – Soberman Feb 16 '16 at 19:03
  • Yep, that was the case. Be careful, when you have multiple targets in your project! – orkenstein Mar 30 '16 at 13:35
  • 15
    Why does this work? And why does this not work out of the box in XCode? – yurgis Nov 08 '16 at 00:50
  • 6
    These line are worth gold!!! Thanks very much. Helped me solving endless Mach-O linker errors in a project with unit-test, ui-test and different deployment targets. – Darkglow Jan 24 '17 at 11:12
  • 3
    I had to do this with a brand new project created with XCode 8.2. – MdaG Feb 04 '17 at 12:01
  • 2
    I have too add in Bundle Loader - $(TEST_HOST). Using xcode 9.2 with objective C and Swift – Lucas Novaes Apr 02 '18 at 19:15
  • 4
    ADDITIONALLY NOTE - Step > Go back to your app target (not the test target), set the Symbols Hidden by Default build setting to NO This option will be visible only when you select "All" under BUILD SETTINGS – Narendra Chandratre Apr 10 '18 at 10:02
  • 1
    Thank you. Spent hours on this – DanielZanchi Dec 19 '18 at 17:38
  • 1
    Wow! wasted almost 4 hrs fighting with such error in my UITest target. Only your solution worked! – Vaibhav Misra Sep 24 '19 at 05:36
  • 2
    Thank you! This fixed my issue `Undefined symbols for architecture x86_64 _OBJC_CLASS_` in my UITest target. I've also spent a lot of time on this issue. – MattCodes Jan 21 '20 at 14:31
  • 1
    Many Thanks to you dude. Wasted hours banging my head on wall for this. Tried Cleaning Derived Data, Restarting Xcode, Restarting Mac and only this solution worked. – Ultimate_93 Apr 22 '20 at 07:04
  • 1
    Thank you for this GOLD my friend, while I still think Apple must do these tricks out of the box. I've created project with xCode 12 and tests embedded - and still needed those hacks – iago849 Oct 22 '21 at 14:55
  • Burned through many, many hours trying to solve this one. Thankyou. Apple, I just have a few questions: Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! Why?! – tomblah Sep 30 '22 at 10:14
22

At least as of Xcode 7.3 test targets let you select a "Host Application". In the Test target (but not presently the UI Test target) this automatically populates the "Test Host" build setting, but not the "Bundle Loader", which can lead to classes not being found.

Considering this, if you set your test targets' "Bundle Loader" Build Setting to $(TEST_HOST), it will always contain the right value even if you change the Host Application.

This is effectively the opposite of the advice given in the link @yuwen-yan posted, and should amount to less work.

Ben Thielker
  • 4,104
  • 4
  • 21
  • 20
  • 2
    I found `$(TEST_HOST)` to be the default configuration, however still one of my pods isn't found. – Lars Blumberg Jun 08 '16 at 09:27
  • 2
    In Xcode9.2, its now under Test target > Build settings > Testing > Test host. Adding $(TEST_HOST) still works. However, I also did update my cocoapods. – quik_silv Aug 02 '18 at 21:40
11

This error may be the result of having wrong test target type, namely ui test target.

UI test targets can't use the internals of the main target, not even with @testable imports. Unit test targets OTOH can use the internals.

See more details in this answer.

(I believe this has changed in some XCode version which causes confusion. Typical way is just to include a huge bunch of files from the original target in the ui test target. A proper way is to design UI tests in such a way that they don't need or use much code from the main target.)

Peter Lamberg
  • 8,151
  • 3
  • 55
  • 69
7

In my case,I got this error when I need to test class that exist in framework that was part of my app :

testing framework class.
1. Add testing target to macOS .
2. Select project/targets window. Select the test target.
3. Go to “build phases”, “link binary with libraries”, add the framework you want to test .
4. In the test class (setup/teardown), add “import” to the class you want to test from that framework

user1105951
  • 2,259
  • 2
  • 34
  • 55
5

Experienced the same issue. What fixed it for me was setting enable modules (c and objective-c) to YES in the Testing target Build Settings.

Raz
  • 2,633
  • 1
  • 24
  • 44
4

In my particular case I was trying to test release configuration and was getting this particular error. After experimenting with different compilation flags I found out that setting Enable Testability for release configuration on my projects (not particular targets but might work too) did the trick.

enter image description here

Fyodor Volchyok
  • 5,610
  • 4
  • 28
  • 45
4

Xcode 12.3 (12C33) – I just removed the testing targets and all references. Then created fresh new test targets, and, added back all my test files ✓ just works

StackUnderflow
  • 2,403
  • 2
  • 21
  • 28
3

What worked for me was just using the test target on the podfile.

target 'MyAppName' do
  use_frameworks!

  pod 'SwiftLint'
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'RxDataSources'
  pod 'RxGRDB'

  target 'UnitTestTarget' do
    inherit! :search_paths  
  end
end
Bruno Muniz
  • 316
  • 3
  • 17
3

I had a unit test target which would not run because of missing symbols.

What fixed it for me was going to

Project -> Targets -> myTestTarget -> Build Phases -> Link Binary With Libraries

and adding the missing library there. I'm using SPM to manage this dependency, probably it was not added properly.

Alain Stulz
  • 715
  • 6
  • 19
2

Experienced the same linker error after adding test target to old project which was created 2 or 3 Xcode versions ago. Furthermore, project has various xcodeproject/target/bundle names. All possible renames, cleanings, Build settings, Build phases, Scheme manipulations did not worked for me.

What did actually worked after a long struggle is recreating the project along with all targets from scratch in latest Xcode version. It finally links! And in this case you don't even need to manually modify Search paths, Bundle loader, Xcode will do it for you.

pkamb
  • 33,281
  • 23
  • 160
  • 191
1

My two cents for people like me getting this error using new(2019..) SPM. I got the same error importing a package in an (old) app.

As importing packages force You to choose target:

enter image description here

Doing so, you don't have it in Tests, unless You:

a) add Host application too test targrt b) flag "Allow testing Host Application APIs"

as here:

enter image description here

now remains the question how to test an app without running App too during testing....

ingconti
  • 10,876
  • 3
  • 61
  • 48
0

For me I got a similar error message when I tried writing and running unit tests in a project that previously only had UI tests. After many hours of troubleshooting, I realized the problem was that my current testing target was only for UI tests, not unit tests.

To fix, I just needed to add a new Unit Testing Bundle target, and then make sure that each unit test file I was trying to run had its Target Membership set to the new target I just created.

wristbands
  • 1,021
  • 11
  • 22
-2

So here is what worked for me...

override func setUp() {

    super.setUp()

    let promise = expectation(description: "App has finished running")

    DispatchQueue.global(qos: .background).async{
        // Wait on the background thread
        sleep(4)
        DispatchQueue.main.async {
            // Fullfill the promise in the main thread
            promise.fulfill()
        }
    }

    // Initialize the storyboard
    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    // Get the view controller
    sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController
    _ = sut.view

    waitForExpectations(timeout: 5) { (_) in
        // Finish set up after the app is done running its code
    }

}// End setUp() Method
Deo Kalule
  • 15
  • 1
-3

Below are the steps that I performed to fix the issue while trying to add unit test target in Xcode 9:

  1. Go to 'Manage Schemes'.
  2. Click on '+' button at the bottom.
  3. Select the newly added Target and select 'OK'.
  4. Make sure 'Shared' option is selected for the newly added target.
Nish
  • 545
  • 5
  • 7