Whats the alternative of #testable import in Objective C - ios

I am working with Unit Testing in Xcode using XCTest provided by Xcode in objective C.
I know how to import Module in Swift like below.
#testable import AppName
Whats the alternative in objective C.

#testable overrides access rights in Swift, allowing you to test internal methods in unit tests.
Objective-C has no such access modifiers, therefore you don't need #testable and you just import the module normally.
If you need to unit test internal Swift methods, you will have to write your tests in Swift.

In Objective C you can simply #import them, as there are no such "internal" method access limitations as in Swift.
Also, On Xcode 6 your main target should be already linked to the test target. If not, try to check the "Allow testing Host Application APIs" checkbox inside Your Test Target > General > Testing. Take a look at this question for more information.

Related

Swift Unit Testing in Xcode is not finding any Objective-C types

I'm trying to write some unit tests in Swift in Xcode. I'm needing to make use of two Swift files because they have the classes I need to utilize in this unit test.
These two Swift files build and run properly when I normally build/run my project.
However, when I attempt to use them in my unit test, I get errors for any types that are referenced in these two Swift files that are coming from any Objective-C file.
See this image:
These missing types are coming from an Objective-C file. Now, these Objective-C files ARE included in my bridging header file so that's not the problem.
I have no other info to work off.
I figured it out. I was missing #testable in the import statement. After adding #testable, it works.

#testable import moduleName not importing everything

I have a project that is mixed Obj-C and Swift and I am having some issues getting my unit tests to work.
I'm using the #testable import moduleName directive to import my files, however it does not appear to be importing all the files. I have full access to pretty much all of my Obj-C models, manager classes etc. but none of the view controllers (95% of which are in Obj-C) are available from within the XCTestCase, along with all of my Swift files.
I have imported #testable import ModuleName at the top of the XCTestCase,
I have also edited the target to enable testability, but the only way I can access these files seems to be if I set the files target membership manually, which if I have understood everything correctly, I should not need to do.
Any suggestions?
Yeah I just also went from the same problem about the Unit testing with the project having both Objective-C & Swift languages.
So basically what i found was
You have to add the respective file and all the required files to Test target. And also required to add them to the Bridging_Header to access those files
Moreover the reason behind using the
#testable
is to test methods internal .... methods.
#testable import moduleName
This is used for the purpose of visibility of methods, i.e like internal methods can now be visible in unitTest but atill private methods won’t.

Cannot see Swift classes from test target

I have an iOS app using both ObjC and Swift code. I tried setting up a test target for it today with no success. I have a single test case class written in Swift. I imported my app's module there. I made sure the classes I am trying to access are public. But I cannot see them from my test target. I can see ObjC code from there though.
I tried the exact same steps on a dummy project and there it worked fine.
I don't want to add the classes for testing to the test target's compile sources. I am also using Xcode 6.3 and updating to Xcode 7 is not an option for me at the moment.
Any ideas on what I am doing wrong?
Make sure your import is marked with a #testable annotation. For example, you want:
#testable import myprojectname
as opposed to:
import myprojectname
The issue went away after deleting and recreating the test target.

How to import a Swift framework globally?

I want to have a way to import my Swift Cocoapods globally in every class, how can I achieve this?
I tried a lot of things and they didn't work. Here are some ways I haven't tried and thought may be possible if found a way to work them:
Have a general import statement like UIKit and put everything in there. (Edit: This failed)
Somehow put Swift frameworks in the Obj-C briding header and import the stuff in there.
You should be able to import it globally by adding #_exported before the import.
#_exported import MyPodModuleName
However, like the other answer mentions, doing that for an entire module is not recommended, because it introduces implicit coupling between modules.
Hence instead try something like:
import Foundation
#_exported import class MyModuleName.MyClassName
#_exported import class MyModuleName.MyOtherClass
It's strongly discouraged in Swift because that would introduce implicit coupling between modules.
However, you can make a certain symbol available globally by declaring a typealias in the module that imports the other module:
import ModuleName
public typealias ClassName = ModuleName.ClassName
As of Swift4:
Being in a Swift project
Want to have another Swift project globally
imported (and using cocoapods)
I just managed to do that by adding the following line to my bridging header:
#import <PodName/PodName-Swift.h>
How good/bad this practise is? Not sure, but I just wanted some extensions globally available in my project. this did the trick.
There is no way to do this. And this is not a bug, this is a language feature (so far, as speaking of Swift 2.2).
Swift uses modules (Apple introduced them in Xcode 5 for Objective-C) and each file is an semantic unit, so you need to explicitly inform Xcode which modules are exposed to defined file.
Not only there is no support for your described behaviour, but you shouldn't also try to bypass it. Using unnecessary (unused) modules could theoretically produce slower code (taking into account that compiler uses this information to its optimisation process).
You can manually achieve the same functionality by:
Creating the Objective-C Bridging Header file;
Adding #import <UIKit/UIKit.h> to the Objective-C Bridging Header file (so that you don't need to repeat this for every single .swift file).
for pods you have to do like #import <SwiftyJSON/SwiftyJSON-umbrella.h>
A reason you wouldn't want to do this:
Imagine if both your frameworks would use the same method name, it would make things ambiguous for the compiler.The compiler won't know which method it should run.
To find out more see this question

Tests with Quick and Nimble

I installed Quick and Nimble frameworks for tests in Swift. But inside test class my class' types is unresolved. In the top of test class I make imports:
import UIKit
import Nimble
import Quick
import MyProject
I know my main target should be at target dependencies and no classes files (except test classes) should be added to compile sources of test target.
Why my files is not visible in test target?
In XCode 7, you can include internal ivars with a line:
#testable import
No need to make the ivars public if you want to keep them conceiled from the outside world...
You need to declare your classes as public. Otherwise, you won't see anything from your test bundle
Also, the default access level of every property/ function is just its own target. So you also need to declare them public

Resources