Swift, access modifiers and unit testing
I just upgraded to Xcode 6 beta 4, where the Swift compiler now supports access modifiers.
That caused a problem for me, since my unit tests now fail to compile (due to the classes not being public).
The simple solution is of course to make all tested classes public, but that feels like a hack (my personal preference is to write unit tests even on non-public classes).
In .NET and Java, you can normally allow unit tests assembly-level (or bundle-level in Java/OSGi) access to the assembly under test from the unit test assembly. I did not understand how to do something similar in Swift. Do I really have to make all my classes public to unit test them?
- How to run a fresh install of the application every time unit tests are run?
- SenTestingKit in Xcode 4: Asynchronous testing?
- Adding Swift Unit Tests to a Mixed Language Xcode Project
- Issue testing and using Cocoapods in a Swift project
- In unit test, execute the block passed in queue with dispatch_asyc
- Objective C - Unit testing core functionality in private methods?
4 Solutions Collect From Internet About “Swift, access modifiers and unit testing”
This is a known issue and mentioned in the Beta 4 release notes. You might want to hold off changing your designs until more information is provided.
We’re aware that our access control design isn’t great for unit testing (and this was in the release notes), we’re evaluating the situation to see what we can do.
— Chris Lattner
A limitation of the access control system is that unit tests cannot interact with the classes and methods in an application unless they are marked public. This is because the unit test target is not part of the application module.
— Xcode beta 4 release notes
With Swift 2 you are now allowed to test your class without have to marked it as public. You just have to use the keyword
@testable and the compiler will take care of rest.
Slide from What’s new in Xcode WWDC 2015:
You can just add the source files from your target to the test target. Then they will be a part of your test target and you will be able to access them.
I think I have a better solution than making everything public. Simply make the StoryBoard a member of the test target just as you do with all your ViewControllers. Then create the StoryBoard in your test class using your test bundle instead of using nil or the main bundle. Check my post here for sample code.
var storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType)) vc = storyboard.instantiateViewControllerWithIdentifier("LoginVC") as LoginViewController vc.loadView()
- How to select Multiple rows in UITableView?
- Cocoapods Warning – CocoaPods did not set the base configuration of your project because because your project already has a custom config set
- UIBezierPath Triangle with rounded edges
- Errors when making circular reference imports
- Xcode 8 (Swift 3) Command failed due to signal: Killed: 9
- How to show ProgressBar With AFNetworking AFHTTPRequestOperationManager
- iOS PhoneGap Build Failure
- Core data find-or-create most efficient way
- ios sort array with dictionaries
- dynamically add Items to TTLauncher
- Perforce Checkout Macro for XCode4
- NSInternalInconsistencyException (invalid number of rows)
- How to rotate UIAlertController in Swift
- XCode 5 – AppleScript – How to get document in current tab
- Creating a selector from a method name with parameters