问题
If I have some library with methods like:
public struct Foo {
@available(macOS 10.15, *)
func greatNewFeature() -> String {
return "new feature"
}
func legacyFeature() -> String {
return "legacy feature"
}
}
Then some code that uses it:
func methodToTest() -> String {
let foo = Foo()
guard #available(macOS 10.15, *) else {
return foo.legacyFeature()
}
return foo.greatNewFeature()
}
Is there a way I can write unit tests which give me complete coverage of methodToTest
?
All ideas I have had so far, have not been helpful:
- you can't treat the availability check as injected functionality - the compiler specifically needs the
@available
keyword in order to use thegreatNewFeature
method. - you can't add some hacky boolean which you could set in the tests like
#available(macOS 10.15, *) || isMacOS10_15
for a similar reason to the previous point.
The only thing I think would work is to run the test suite multiple times - once for each supported OS version, then create a script to combine the code coverage stats. Can anyone think of a better approach?
回答1:
You can create a flag in your tests whether to skip the OS version check or not and &&
that with your #available
check.
This way you simply need to call testFooFeature
with the flag both turned on and off and you'll be able to test both code paths on macOS 10.15
.
var forceOldOSVersion = true
func testFooFeature() -> String {
let foo = Foo()
if !forceOldOSVersion, #available(macOS 10.15, *) {
return foo.greatNewFeature()
} else {
return foo.legacyFeature()
}
}
testFooFeature() // "legacy feature"
来源:https://stackoverflow.com/questions/61084603/testing-codepaths-for-older-os-versions