You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Martin Heidegger <mh...@leichtgewicht.at> on 2012/02/07 21:11:36 UTC

[RT] From Singletons to Unit-testable code

Hello List,

when thinking about unit testing of Flex components I got a strong 
argument against it due to the heavy use of Singletons throughout the 
project. I think I might have a good refactoring path to ease the 
transition from the current code to a code that might be easier manageable.

The following process has the advantage that from an early stage it 
would be possible to write unit tests and at all times it can still be 
deployed!

1) Create a global context system

   interface IFlexContext {
     function getProperty(name: String):* {}
   }
   public static var FLEX_CONTEXT: IFlexContext = new DefaultFlexContext();

2) copy the code that currently resides in static methods to the 
DefaultFlexContext();

   mx_internal static function get 
embeddedFontRegistry():IEmbeddedFontRegistry {
      return FLEX_CONTEXT.getProperty("UIComponent.embeddedFontRegistry");
   }
    class DefaultFlexContext {
      function getProperty(name: String): * {
        if( name =="UIComponent.embeddedFontRegistry" ) {
          if (!_embeddedFontRegistry && !noEmbeddedFonts) {
            try {
               _embeddedFontRegistry = IEmbeddedFontRegistry( 
Singleton.getInstance("mx.core::IEmbeddedFontRegistry"));
            } catch (e:Error) {
              noEmbeddedFonts = true;
            }
          }
          return _embeddedFontRegistry;
        }
      }
   }

3) We create unit tests that use these contexts to see with a blind 
implementation if certain parts of code rely on those static mechanisms. 
In a way that we can interact with them. From now on all changes will 
reflect in broken unit tests. Yey! Also no API is broken in the system. 
This is very important!

4) When we have the unit tests up and running we start to remove the 
static calls to use the context instead:

    return embeddedFontRegistry;

becomes:

    return FLEX_CONTEXT.getProperty("UIComponent.embeddedFontRegistry");

5) We put the Flex context in a private variable that can be set from 
outside.

   return FLEX_CONTEXT.getProperty("UIComponent.embeddedFontRegistry");

    becomes:

     private var _context: IFlexContext = FLEX_CONTEXT;
     public function set context(context: IFlexContext) {}

    ....
    return _context.getProperty("UIComponent.embeddedFontRegistry");

6) We adapt the unit tests to actually set this context per instance 
instead of setting the context globally

7) We change the logic of addChild/removeChild to automatically set the 
current context

8) We extract the different modules in own variables
     private var _fontContext: IFontContext;

     return _fontContext.getProperty("embeddedFontRegistry");

9) We reintroduce custom methods:

      return _fontContext.embeddedFonts;

I know that this approach is quite a long one but I think it could be 
done step by step without creating too much friction at each point in time.

What do you think?

yours
Martin.


RE: [RT] From Singletons to Unit-testable code

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>The dependency injection requires to rewrite a lot without having unit test on the way. I think at the end of mentioned process we could simply switch to a DI model.

To me it looks like the opposite. I think the amount of rewrite here would be more than injecting dependencies. Just my thoughts though

Notice: This transmission is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged or confidential. Any dissemination, distribution or copying of this transmission by anyone other than the intended recipient is strictly prohibited. If you have received this transmission in error, please notify the sender immediately by e-mail or telephone and delete the original transmission. Thank you.

Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 05:20, Michael A. Labriola wrote:
> Or, if you were going to go through all of that refactoring, you could 
> use a dependency injection rather than service locator pattern 
The dependency injection requires to rewrite a lot without having unit 
test on the way. I think at the end of mentioned process we could simply 
switch to a DI model.

yours
Martin.




RE: [RT] From Singletons to Unit-testable code

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>>when thinking about unit testing of Flex components I got a strong argument against it due to the heavy use of Singletons throughout the project. I think I might have a good refactoring path to ease the transition >>from the current code to a code that might be easier manageable.

Or, if you were going to go through all of that refactoring, you could use a dependency injection rather than service locator pattern

Notice: This transmission is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged or confidential. Any dissemination, distribution or copying of this transmission by anyone other than the intended recipient is strictly prohibited. If you have received this transmission in error, please notify the sender immediately by e-mail or telephone and delete the original transmission. Thank you.

Re: [RT] From Singletons to Unit-testable code

Posted by Omar Gonzalez <om...@gmail.com>.
>
> There's a reason why IoC containers like SwiftSuspenders have a
> mapSingleton() method,...
>

And when I said that I actually meant the injector in Robotlegs:
https://github.com/robotlegs/robotlegs-framework/blob/8340bfda8d4e60a39617303a5fd09c4183c61de6/src/org/robotlegs/core/IInjector.as

-omar

Re: [RT] From Singletons to Unit-testable code

Posted by Omar Gonzalez <om...@gmail.com>.
>
> And then there is the whole debate about Singletons in general...
> --
> Alex Harui
> Flex SDK Team
> Adobe Systems, Inc.
> http://blogs.adobe.com/aharui
>
>
I don't think the issue a lot of devs have with Singletons is actually with
the concept of Singletons itself but the implementation in which most
Singletons are written. There's a reason why IoC containers like
SwiftSuspenders have a mapSingleton() method, and that's because the
concept of a class that should ever only have a single instance is valid
and necessary, but when this is enforced with static properties with the
traditional constructor enforcement and getInstance() static functions it
really hinders the ability to create mock objects when trying to right
clean, truly isolated unit tests. Managing the singleton aspects of classes
using an IoC container ensures that you have a single instance of a class
type but are able to swap out the implementation whether it be for testing
or extending a code base. I could be wrong, I've been wrong lots before
heh, but those are just my thoughts on it.

-omar

RE: [RT] From Singletons to Unit-testable code

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>>My simple mind just can't understand why we need a sophisticated multi-step plan or full dependency injection.  Why can't a simpler substitution pattern do the job?

Alex, first, I am not sure what you think is involved in the injection solution, but I am not sure it is more complicated. To me, in many ways, it seems simpler. We can discuss when I check something in
Notice: This transmission is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged or confidential. Any dissemination, distribution or copying of this transmission by anyone other than the intended recipient is strictly prohibited. If you have received this transmission in error, please notify the sender immediately by e-mail or telephone and delete the original transmission. Thank you.

Re: [Infra] Wiki Account

Posted by Anand Vardhan <ma...@anandvardhan.com>.
Keith,

Please include Pune Flex User Group (PuneFUG.org) in the list too.

Cheers,
Anand Vardhan (+91 956-1818-960)
Adobe Certified Expert,Flex 3.0 & AIR
Adobe Certified Developer, Flex 2.0
www.AnandVardhan.com
www.linkedin.com/in/anandvardhan
“Innovation distinguishes between a leader and a follower.” -Steve Jobs



On Thu, Feb 9, 2012 at 4:35 AM, Doug Arthur <do...@apache.org> wrote:

> On Wed, Feb 8, 2012 at 3:20 PM, Keith Sutton <ke...@spoon.as> wrote:
> > Hello,
> >
> > I have developed a list of 40+ Flex user groups world-wide and would
> like to
> > post a page on the wiki. For more info you can check the [Wiki][User
> Groups]
> > discussion thread.
> >
> > My account is 'keith_sutton' and request editor access.
> >
> > Regards Keith
>
>
> I've added you as an Individual user to the wiki, so you should be
> able to add pages and post. As noted by Bertrand (a podling mentor),
> you may consider filing an ICLA if you have major contributions, but
> don't think it's necessary for what you want to post.
>
> Mentors, is that acceptable, or do you want to add users as committers?
>
> - Doug
>

Re: [Infra] Wiki Account

Posted by Doug Arthur <do...@apache.org>.
On Wed, Feb 8, 2012 at 3:20 PM, Keith Sutton <ke...@spoon.as> wrote:
> Hello,
>
> I have developed a list of 40+ Flex user groups world-wide and would like to
> post a page on the wiki. For more info you can check the [Wiki][User Groups]
> discussion thread.
>
> My account is 'keith_sutton' and request editor access.
>
> Regards Keith


I've added you as an Individual user to the wiki, so you should be
able to add pages and post. As noted by Bertrand (a podling mentor),
you may consider filing an ICLA if you have major contributions, but
don't think it's necessary for what you want to post.

Mentors, is that acceptable, or do you want to add users as committers?

- Doug

[Infra] Wiki Account

Posted by Keith Sutton <ke...@spoon.as>.
Hello,

I have developed a list of 40+ Flex user groups world-wide and would 
like to post a page on the wiki. For more info you can check the 
[Wiki][User Groups] discussion thread.

My account is 'keith_sutton' and request editor access.

Regards Keith



RE: [RT] From Singletons to Unit-testable code

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>>Given some sort of native dependency management in the framework, do we really need styles?

There is some overlap. The biggest problem is the hierarchical nature of styling adds some complexity.

Mike
Notice: This transmission is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged or confidential. Any dissemination, distribution or copying of this transmission by anyone other than the intended recipient is strictly prohibited. If you have received this transmission in error, please notify the sender immediately by e-mail or telephone and delete the original transmission. Thank you.

Re: [RT] From Singletons to Unit-testable code

Posted by Erik Lundgren <er...@lndgrn.se>.
8 feb 2012 kl. 15.25 skrev Michael A. Labriola:

> I am going to provide a version of the framework and compiler with a swappable, minimalistic injection mechanism and perhaps some basic AOPish concepts like compile time mixins. [...] The biggest problem in this approach is actually things like StyleManagement ...

Given some sort of native dependency management in the framework, do we really need styles?

To me CSS just ads complexity to the development-model – a third language/spec introduced to act as a configuration pool for objects to reach out into and self-configurate (getStyle('myMagicString')). And the process of maintaining "magical strings" is painful.

Could objects that need styles not be injected with value-objects written in MXML or ActionScript?

I don't know the DI-mechanism you had in mind, but given how Flex DI-frameworks handle things today, we ought to be able to map objects to objects with the same amount of precision as Flex css does today?

All the best!
/Erik


RE: [RT] From Singletons to Unit-testable code

Posted by "Michael A. Labriola" <la...@digitalprimates.net>.
>I could be wrong but I think the plan I wrote about was a step-by-step instruction to get rid of singletons using a intermediate service locator that can be dropped in the end.

>To me the first step is to get from "unit tests are impossible" (the current state of the framework) to "they are do-able".  Then unit tests could actually be written. With unit tests available it would be safer to ease to >a system without a global state.

As you might expect from my posts, I am planning on taking a different approach in my whiteboard. I am going to provide a version of the framework and compiler with a swappable, minimalistic injection mechanism and perhaps some basic AOPish concepts like compile time mixins. My personal thought is that: if the injection mechanism exists, and if people like the way I approached it, then one by one we can fix individual classes to favor this pattern, slowly increasingly the flexibility and testability of the framework. The biggest problem in this approach is actually things like StyleManagement, which I just can't see a way to tackle without major changes, but that is a discussion for another day.

I have no expectation that my thoughts will be taken wholesale, but I think the best way to solve the debate is to look at the code side by side (even a subset of the code). See the complexity and performance differences and then weigh the options.

Mike


Notice: This transmission is intended only for the use of the individual or entity to which it is addressed and may contain information that is privileged or confidential. Any dissemination, distribution or copying of this transmission by anyone other than the intended recipient is strictly prohibited. If you have received this transmission in error, please notify the sender immediately by e-mail or telephone and delete the original transmission. Thank you.

Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 18:50, David Arno wrote:
> Let's have that debate. Replacing static methods with singletons will 
> not improve the testability of the code. If those static methods are 
> deterministic and have no side effects, then they are fine as static 
> methods (and maybe could be turned into global functions as a minor 
> [though controversial] improvement.) Otherwise, they need to go. 
> Global state, whether via singletons, service locator patterns or 
> static methods, always make testing difficult. If we are serious about 
> making the Flex framework unit-testable, then we need to get rid of 
> all of them and replace them with dependency injection throughout the 
> framework. 

I could be wrong but I think the plan I wrote about was a step-by-step 
instruction to get rid of singletons using a intermediate service 
locator that can be dropped in the end.

To me the first step is to get from "unit tests are impossible" (the 
current state of the framework) to "they are do-able".  Then unit tests 
could actually be written. With unit tests available it would be safer 
to ease to a system without a global state.

yours
Martin


Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 09/02/2012 00:44, Alex Harui wrote:
> I think the simplest is just adding a replaceInstance on mx.core.Singleton...
The replacement in Singleton is just reasonable if all static code was 
actually handled within the singleton code. I tried to explain before: 
there is more code in the statics than just the reference to the 
Singleton and this code can not be ignored. The service locator could 
work without restricting itself to the singleton.


On 09/02/2012 00:44, Alex Harui wrote:
> ....that dispatches an event with what got replaced.
If we have to change the logic of the system so that all static classes 
register to the changes of the event it will certainly result in a lot 
of code.

yours
Martin.



Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.


On 2/8/12 7:33 AM, "Martin Heidegger" <mh...@leichtgewicht.at> wrote:

> I am curious about the "simpler substitution": How would you do that in
> detail?
I think the simplest is just adding a replaceInstance on mx.core.Singleton
that dispatches an event with what got replaced.

And maybe some new list of mixins that get run before the SystemManager
registers the initial set of singletons.

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 23:45, Alex Harui wrote:
> My simple mind just can't understand why we need a sophisticated multi-step
> plan or full dependency injection.  Why can't a simpler substitution pattern
> do the job?

The complexity always comes with the detail. I assume one could 
summarize it with:

   Move the static constructs to a service locator to implement unit 
tests and replace it step by step to get a injectable source code.

I broke the refactoring up in many steps to illustrate that this way 
will be constantly tested from step 2.

Michaels approach as well as your approach will most likely be more 
complex in reality than summarized.
For example: Modifying the compiler, creating an AOP mechanism and then 
changing all code to follow that pattern is a huge project. where each 
part has to be tested.

I am curious about the "simpler substitution": How would you do that in 
detail?

yours
Martin.



Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.


On 2/8/12 1:50 AM, "David Arno" <da...@davidarno.org> wrote:

>> From: Alex Harui [mailto:aharui@adobe.com]
>> Sent: 08 February 2012 03:10
>> 
>> ... And then there are some old singletons like EffectManager that still
> use
>> static methods, which should be using Singleton instead.
>> 
>> And then there is the whole debate about Singletons in general...
> 
> Let's have that debate. Replacing static methods with singletons will not
> improve the testability of the code. If those static methods are
> deterministic and have no side effects, then they are fine as static methods
> (and maybe could be turned into global functions as a minor [though
> controversial] improvement.) Otherwise, they need to go.
I don't fully agree.  I don't see how static methods on a class are
substitutable at runtime without resorting to evil tricks.  Static methods
require hacks for event dispatching and can't implement interfaces.  But for
sure, a bad instance method implementation can also make substitution
difficult.
> 
> Global state, whether via singletons, service locator patterns or static
> methods, always make testing difficult. If we are serious about making the
> Flex framework unit-testable, then we need to get rid of all of them and
> replace them with dependency injection throughout the framework. Anything
> less will - from a testing point of view - just be fiddling whilst Rome
My simple mind just can't understand why we need a sophisticated multi-step
plan or full dependency injection.  Why can't a simpler substitution pattern
do the job?  

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


RE: [RT] From Singletons to Unit-testable code

Posted by David Arno <da...@davidarno.org>.
> From: Alex Harui [mailto:aharui@adobe.com] 
> Sent: 08 February 2012 03:10
> 
> ... And then there are some old singletons like EffectManager that still
use
> static methods, which should be using Singleton instead.
>
> And then there is the whole debate about Singletons in general...

Let's have that debate. Replacing static methods with singletons will not
improve the testability of the code. If those static methods are
deterministic and have no side effects, then they are fine as static methods
(and maybe could be turned into global functions as a minor [though
controversial] improvement.) Otherwise, they need to go.

Global state, whether via singletons, service locator patterns or static
methods, always make testing difficult. If we are serious about making the
Flex framework unit-testable, then we need to get rid of all of them and
replace them with dependency injection throughout the framework. Anything
less will - from a testing point of view - just be fiddling whilst Rome
burns.

David.


Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.


On 2/7/12 10:49 PM, "Martin Heidegger" <mh...@leichtgewicht.at> wrote:


> 
> Uhm, how can folks help you?
> 
Someday, after we get all the code in and test suites running, I hope to
spend 2 days/week on my whiteboard re-write, 3 on shorter term improvements
that folks want including reviewing commits and patches.  We'll see if that
actually happens or not.

I expect at the early stages of my whiteboard work, there will be lots of
discussion around whether folks like my implementation strategy.  Once that
gets settled on, it will be a matter of pulling relevant code from the
current SDK and turning it into useful entities in the whiteboard, and
everyone who is a committer can pitch in.

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 15:31, Alex Harui wrote:
> You can have a back-door to replace singletons if you want to.  That's even
> easier to add to Singleton. For now though, keep in mind that because of
> the stew of dependencies between classes in the framework, you really need
> to restart the app or implement a reset protocol, otherwise something might
> break when you replace a singleton after startup.
Of course replacing the singleton could break a running system. Once its 
all instances then a singleton can't break anything. But more 
importantly: I don't suggest that this "context-replacement" is used 
permanently. Its a refactoring strategy to get to a tested system 
without breaking code.

> folks trying to modify the framework as is, or folks who will help
> me with my re-write.

Uhm, how can folks help you?

yours
Martin.

Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.
You can have a back-door to replace singletons if you want to.  That's even
easier to add to Singleton.  For now though, keep in mind that because of
the stew of dependencies between classes in the framework, you really need
to restart the app or implement a reset protocol, otherwise something might
break when you replace a singleton after startup.

That's why Mike Labriola is saying you can't unit-test the framework per-se.
I agree under that definition, and the question is, who will fix that
faster: folks trying to modify the framework as is, or folks who will help
me with my re-write.


On 2/7/12 10:09 PM, "Martin Heidegger" <mh...@leichtgewicht.at> wrote:

> On 08/02/2012 15:02, Alex Harui wrote:
>> One way is to define another set of mixins that get initialized before
>> the SystemManager starts registering singletons.
>> In my whiteboard re-write, the Singletons will probably be defined in
>> some manifest, will only register just before first use, and there
>> will be an event to give you a definite chance to register replacements.
> That will not enable unit testing. In unit testing the "instances" have
> to be replaced before and after each unit to be tested.
> In other words: A lot of times not just once at startup.
> 
> yours
> Martin.

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 15:02, Alex Harui wrote:
> One way is to define another set of mixins that get initialized before 
> the SystemManager starts registering singletons.
> In my whiteboard re-write, the Singletons will probably be defined in 
> some manifest, will only register just before first use, and there 
> will be an event to give you a definite chance to register replacements. 
That will not enable unit testing. In unit testing the "instances" have 
to be replaced before and after each unit to be tested.
In other words: A lot of times not just once at startup.

yours
Martin.

Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.


On 2/7/12 8:42 PM, "Martin Heidegger" <mh...@leichtgewicht.at> wrote:

> This second part is the reason I wrote this. I am all ears as to how
> this can be fixed more easily!
One way is to define another set of mixins that get initialized before the
SystemManager starts registering singletons.

In my whiteboard re-write, the Singletons will probably be defined in some
manifest, will only register just before first use, and there will be an
event to give you a definite chance to register replacements.

-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui


Re: [RT] From Singletons to Unit-testable code

Posted by Martin Heidegger <mh...@leichtgewicht.at>.
On 08/02/2012 12:09, Alex Harui wrote:
>
> I don't understand what this does other than what mx.core.Singleton already
> does.
Actually there are two points: If you saw the small sample code: The use 
of mx.core.Singleton is not just a simple redirect,
    if (!_embeddedFontRegistry && !noEmbeddedFonts) {
         try {
            _embeddedFontRegistry = IEmbeddedFontRegistry( 
Singleton.getInstance("mx.core::IEmbeddedFontRegistry"));
        } catch (e:Error) {
            noEmbeddedFonts = true;
        }
    }
    return _embeddedFontRegistry;

This method contains a bunch of logic that shouldn't be static. In 
general I was referring not to Singletons in particular but to any 
static code except utils.

> The only issue I know of is there is no place in the application
> lifecycle that gives you a clean chance to swap out the implementation. That
> is much more easily fixed.

This second part is the reason I wrote this. I am all ears as to how 
this can be fixed more easily!

> And then there are some old singletons like EffectManager that still use
> static methods, which should be using Singleton instead.
I think that is something that the community easily can take care of.


> And then there is the whole debate about Singletons in general...
At the end of this refactoring all singletons would be gone.

yours
Martin.

Re: [RT] From Singletons to Unit-testable code

Posted by Alex Harui <ah...@adobe.com>.


On 2/7/12 12:11 PM, "Martin Heidegger" <mh...@leichtgewicht.at> wrote:

> Hello List,
> 
> when thinking about unit testing of Flex components I got a strong
> argument against it due to the heavy use of Singletons throughout the
> project. I think I might have a good refactoring path to ease the
> transition from the current code to a code that might be easier manageable.
> 

> I know that this approach is quite a long one but I think it could be
> done step by step without creating too much friction at each point in time.
> 
> What do you think?
I don't understand what this does other than what mx.core.Singleton already
does.  The only issue I know of is there is no place in the application
lifecycle that gives you a clean chance to swap out the implementation. That
is much more easily fixed.

And then there are some old singletons like EffectManager that still use
static methods, which should be using Singleton instead.

And then there is the whole debate about Singletons in general...
-- 
Alex Harui
Flex SDK Team
Adobe Systems, Inc.
http://blogs.adobe.com/aharui