Background: I want to test private methods with XCTest, so I'm searching for a elegant solution to expose private methods to my XCTestCase classes.
Disclaimer: Some people have the opinion that it's fundamentally wrong to test the internals of your classes. In practice I disagree because when tests break, testing privates can make tracing down the issue much easier.
Swift private functions are private to the file, and private really means private, thus there is no way to expose private functions to other files. Using preprocessor macros, private functionality can be exposed via public functions for just one build configuration. For example, I have a TEST
compile flag setup for my Test configuration which my Test scheme uses.
So far, this is the best solution I have, but it requires annoying boilerplate for every private function that needs testing:
In ClassThatNeedsTesting.swift:
class ClassThatNeedsTesting {
#if TEST
func publicAccessToPrivateFunctionThatNeedsTesting() -> Bool {
return self.privateFunctionThatNeedsTesting()
}
#endif
private func privateFunctionThatNeedsTesting() -> Bool {
return true;
}
}
In TestClass.swift:
class TestClass: XCTestCase {
func testExample() {
XCTAssert(ClassThatNeedsTesting().publicAccessToPrivateFunctionThatNeedsTesting());
}
}
But is there a way to simplify this with inline preprocessor macros? This is what I want, but it doesn't compile, hence why I'm asking:
In ClassThatNeedsTesting.swift:
class ClassThatNeedsTesting {
#if TEST private #endif func privateFunctionThatNeedsTesting() -> Bool {
return true;
}
}
In TestClass.swift:
class TestClass: XCTestCase {
func testExample() {
XCTAssert(ClassThatNeedsTesting().privateFunctionThatNeedsTesting());
}
}
If there's no way to do this, perhaps there's a simpler solution?