Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 328
Krumelur Avatar asked Jul 28 '14 11:07

Krumelur


People also ask

How does swift implement unit testing?

Writing Unit Test Cases in Swift With an ExampleUnit test cases run with the testing target. Always check if you have a unit test target or not, if not, then add it. Then under this target, you need to create a new test case file. You will use this new file for writing test cases.

What are the access modifiers in Swift?

In Swift 3 and swift 4, we have open, public, internal, fileprivate, and private for access control. Open access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level.

What is unit testing in Swift?

A unit test is a function you write that tests something about your app. A good unit test is small. It tests just one thing in isolation. For example, if your app adds up the total amount of time your user spent doing something, you might write a test to check if this total is correct.

How do you unit test private functions in Swift?

Access Control You probably know that you can apply the testable attribute to an import statement in a test target to gain access to entities that are declared as internal. import XCTest @testable import Notes class NotesTests: XCTestCase { ... }


3 Answers

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

https://github.com/ksm/SwiftInFlux#limitations-of-current-access-control-design

like image 156
Chris Wagner Avatar answered Oct 10 '22 11:10

Chris Wagner


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:

like image 35
Max_Power89 Avatar answered Oct 10 '22 09:10

Max_Power89


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.

like image 43
Sulthan Avatar answered Oct 10 '22 10:10

Sulthan