[swift-evolution] Readwrite reflection in Swift
david.ndh at gmail.com
Mon Dec 21 18:28:15 CST 2015
I think this is something really valuable in multiple cases and I'm
particularly interested in having this to improve the usage of inversion of
control. However, I wonder if this is possible due the strong static typing
from Swift or if it may not reduce the safety of the language.
But I found the current limitations regarding this matter very educational
actually, because enforces us to really design our code using interfaces
instead of concrete implementations which aligns with one of the SOLID
principles, Dependency inversion.
In your example for example, by adopting this principles we should not rely
in the instance of UIApplication directly but instead define an interface
that represents this intention of opening an URL like you have suggested.
But I think this is valuable not only because it makes the code testable
but specially because we can achieve an abstraction of UIApplication class
itself making it reusable. Suppose that you want to reuse this code in
another architecture, e.g. Linux, having this abstraction you will not need
to adapt your code but instead only provide a concrete implementation for
your current target, Linux, iOS or even unit-tests.
2015-12-18 22:09 GMT+00:00 Gergely Orosz via swift-evolution <
swift-evolution at swift.org>:
> 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.
>> 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?
> swift-evolution mailing list
> swift-evolution at swift.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution