skip to Main Content

I want to create a function or convenience init of a class that can not be available for TestTarget when import with @testable import, I am not sure it’s possible but looking for any way to restrict it.

class A {
   // Should not be accessible in Test Target
   func foo() {
   }
}

In Testing when @testable import it should not be available.

/**********
UPDATE
***********/

Problem statement

The Long param init method is used with convenience methods to provide default arguments but then in testing, I don’t want to access that convenience method with the default argument because it’s easy to forget to provide mock depedancy.

3

Answers


  1. Mark that function as Private. Then it will not be available in test target.

    You cannot access private entities from another module and this also applies to test targets. That is what access control is for.

    Login or Signup to reply.
  2. There are two solutions to do so.

    1. You can add the following code in your init
    #if DEBUG
    if let _ = NSClassFromString("XCTest") {
        fatalError("Should not be used in unit test.")
    }
    #endif
    

    With this solution, you can still use this init in your unit test, but it will crash at runtime.

    1. Add a new configuration Testing, you can do this by Select your debug config -> Click + -> Duplicate Debug, and rename it to Testing
      enter image description here

    then in your main target, add a new flag TESTING in the config Testing.
    enter image description here

    Next go to Product -> Scheme -> Edit Scheme Set build configuration to Testing for your Test
    enter image description here

    Finally add this around your init.

    #if !TESTING
    init() {}
    #endif
    

    Now, you should not be able to use this init in your unit test.

    Login or Signup to reply.
  3. You could just import the module as opposed to @testable import.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search