17

Im trying to test some Swift class (@objc class) in my legacy Objc code. I am importing "UnitTests-Swift.h" in my test classes.

Then I get this error:

Module "MyApp" not found in the autogenerated "UnitTests-Swift.h"

This is whats inside the top part of the "UnitTests-Swift.h"

typedef int swift_int3  __attribute__((__ext_vector_type__(3)));
typedef int swift_int4  __attribute__((__ext_vector_type__(4)));
#if defined(__has_feature) && __has_feature(modules)
@import XCTest;
@import ObjectiveC;
@import MyApp;
@import CoreData;
#endif

I cleaned the project, checked all the relevant flags ("No such module" when using @testable in Xcode Unit tests, Can't use Swift classes inside Objective-C), removed derived data and so on.. No idea of whats happening, but I m quite sure that @import MyApp shouldnt be there..

Can anyone help me with this?

Community
  • 1
  • 1
Piga4
  • 279
  • 4
  • 8

4 Answers4

7

Just got this issue in my project and after the entire day spent on investigation I finally resolved it. Basically this happens because you have cyclic dependency between ObjC and Swift. So in my case it was:

  • Swift Protocol with @obj attribute in a main target;
  • Swift Class in UnitTest target which inherited this Protocol;
  • Import UnitTestTarget-Swift.h in any Objective-C class of your UnitTest target

So fairly simple combination leads to this error. In order to fix this you want either:

  • simply make sure that your Swift Class in UnitTest target is private, so it won't get to UnitTestTarget-Swift.h

or

  • do not mark your original Swift Protocol as @objc, which will allow you to access your SwiftClass from all ObjectiveC test classes, but those classes won't have any idea about the Swift Protocol.
Oleg Kohtenko
  • 383
  • 5
  • 14
1

This solution helped me:

  1. Open Tests Target Build Settings
  2. Search for HEADER_SEARCH_PATHS
  3. In the line called "Header Search Paths" set value $CONFIGURATION_TEMP_DIR/myProjectName.build/DerivedSources
  4. Clean and Cmd+U again

Hope it helps!

Many thanks to this article.

Tung Fam
  • 7,899
  • 4
  • 56
  • 63
0

Because the Swift class to be tested is part of MyApp, you should be importing "MyApp-Swift.h" in the test classes instead of "UnitTests-Swift.h".

Rein Spijkerman
  • 604
  • 5
  • 15
0

You can add a Swift unit test (just create a new unit file and change the extension by .swift).

From that unit test file you can use your Swift classes.

And you can also import that file from your Objective-C unit tests (and the other way around) using the test module bridging headers.

And this would be the default example for your Swift unit test file:

import XCTest
@testable import MyApp

class MyAppSwiftTests: XCTestCase {

  override func setUp() {
    super.setUp()
    // Put setup code here. This method is called before the invocation of each test method in the class.
  }

  override func tearDown() {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    super.tearDown()
  }

  func testExample() {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
  }

  func testPerformanceExample() {

    // This is an example of a performance test case.
    self.measure {
      // Put the code you want to measure the time of here.
    }
  }
}
FranMowinckel
  • 4,233
  • 1
  • 30
  • 26