[swift-evolution] Readwrite reflection in Swift

Gergely Orosz gergely.orosz at gmail.com
Fri Dec 18 16:09:49 CST 2015


>
> Also consider alternatives to the use cases you described—mocking and data
> modeling can also be accomplished by compile-time code generation, and by
> features like type providers that supply external type information to the
> compiler. Runtime reflection is definitely useful in many cases, but
> compile-time approaches are likely to be easier to verify and maintain,
> faster, and more secure.
>
> -Joe
>
> I am aware of the current alternative of specifying dependencies to be
mocked complile time. However I see a major issue on how protocols need to
be added that are only used by the test code - yet they ship as part of the
production code.

For example consider a method that opens an external URL from the
application by invoking the UIApplication.sharedApplication().openUrl(...)
method. In order to write a unit test to verify this call is being made a
new protocol needs to be specified that defines the openUrl() method, as
UIApplication does not implement any protocols (lets call this
UIApplicationProtocol). Then via an extension UIApplication needs to
inherit this UIApplicationProtocol, and the original code can be changed to
use a UIApplicationProtocol dependency when invoking openUrl().

My main issue is that UIApplicatipnProtocol is not used anywhere in the
production code, but purely added to enable testing. The same applies for
any developer specified class - to enable testing often a matching protocol
needs to be specified, even if this protocol is not needed or used by the
production code.

If in order to be able to unit test production code, that code needs to
ship with test-only code, then I do feel that indicates that the language
is not very "test friendly". In Objective C one can write production code
as simple as intended and by replacing methods runtime do all the testing
they want in their test project. Of course there is a performance hit -
however the vision of Swift is to get all the benefits of Objective C
without having to worry about performance

Being able to opt in to reflection would be a good start - this would give
developers an option to choose whether or not to sacrifice any performance
for the sake of a bit cleaner code (no test-only protocols).

Howeve opt-in reflection will still not solve how to unit test calls to
foundation classes like in my example - will the recommendation be for
developers to specify their own extension protocols for these foundation
class methods they want to test? Or would it make sense for all foundation
classes to also implement a protocol to give more support for this kind of
unit testing?

Also for test code performance is much less of an issue - would it be
feasible to apply different restrictions to reflection for test projects?
In a similar way to how the @testable declaration sidesteps some of the
security limitations of non-public members, could @testable also be used to
relax reflection restrictions for the imported code?

Thanks,

 Gergely
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151218/a9f1bcaa/attachment.html>


More information about the swift-evolution mailing list