Using [Inject] and listening to framework events in FlexUnit test cases

stevensacks's Avatar

stevensacks

13 Dec, 2009 09:52 PM

I don't know the right way to set up FlexUnit test cases where I require access to the framework to know if the test passed or failed.

I have classes that extend Actor that dispatch events to the framework, and those events will determine whether or not the test passed. Currently, I cannot figure out how to have a test case listen to the framework to assert the test passed, or how to use [Inject] inside a test case to access classes I map as singletons in my context.

Because my application is fully integrated in RobotLegs, there are many tests that require events going through the framework, and listening for events that are dispatch()ed from an Actor.

Any guidance would be greatly appreciated

  1. Support Staff 1 Posted by Joel Hooks on 13 Dec, 2009 10:17 PM

    Joel Hooks's Avatar

    I have classes that extend Actor that dispatch events to the framework, and those events will determine whether or not the test passed. Currently, I cannot figure out how to have a test case listen to the framework to assert the test passed, or how to use [Inject] inside a test case to access classes I map as singletons in my context.

    You don't need to have a context in this situation, simply manually inject an IEventDispatcher into the class under test and have your async test methods listen to it for results. We aren't interested in "events going through the framework" in our tests, and in fact shouldn't be interested in the framework at all. By their nature, Actors and other general application actors live in a loosely couple isolated state. In our tests, we provide only the dependencies needed for the test to pass, and don't worry about the fact that the class under test resides in a broader application scope.

    The Image Gallery demo has some tests that illustrate this briefly. Short answer is a test case should never instantiate a Context, unless you are testing the Context.

    On Dec 13, 2009, at 3:52 PM, stevensacks wrote:

  2. Support Staff 2 Posted by Shaun Smith on 13 Dec, 2009 10:18 PM

    Shaun Smith's Avatar

    A quick way to get up to speed with how Robotlegs is put together is to open up org.robotlegs.mvcs.Actor.

    It's important to understand that it is not a "special" class in any way - it is simply a class with a dependency on an IEventDispatcher. Also, have a look at org.robotlegs.mvcs.Command. Again, it's not a special class (it doesn't even extend anything), it's just a regular class with some pre-defined dependencies. The same is true of all classes in the framework. They are standalone classes with dependencies defined either as constructor arguments or annotated public fields.

    Events in Robotlegs are not framework events - they are just normal events dispatched along whatever IEventDispatcher an instance has been given.

    So, in order to unit test a class that extends Actor all you have to do instantiate it and supply the dependencies manually, For example:

    var myActor:MyActor = new MyActor();
    var eventDispatcher:IEventDispatcher = new EventDispatcher();
    myActor.eventDispatcher = eventDispatcher;
    myActor.someOtherDependency = new SomeOtherDependency();
    

    Now, you have an actor to test along with a reference to an IEventDispatcher, and you can test whether certain events are fired on that dispatcher.

    The instances in a Robotlegs application are wired together by rules given to a Dependency Injection container. When Robotlegs creates a Mediator, for example, it asks the DI container for a new Mediator. When it creates a command, it asks the container for a new command. Any dependencies that a Mediator or Command might have will be resolved by the injection container when it instantiates an instance of such a Mediator/Command.

    But the container has to be told how to resolve these dependencies. It needs a rule for every injection point it encounters when it is asked for an instance of something.

    Many rules are set up for you - Robotlegs even creates some temporary rules when it creates a Command (a temporary rule for the event that triggered the command) or Mediator (a rule for the view component associated with the mediator) - but for everything else, you'll need to set the rules up yourself.

    The nice thing about these rules is that they are lazy - instances are not created until they are needed. Automated Dependency Injection is very handy in a static language like AS3.

  3. Support Staff 3 Posted by Shaun Smith on 13 Dec, 2009 10:31 PM

    Shaun Smith's Avatar
  4. 4 Posted by stevensacks on 13 Dec, 2009 10:45 PM

    stevensacks's Avatar

    Thanks for the info. Manually supplying the event dispatcher is the answer I was looking for.

    I assume that in the test case, I addEventListener() to the EventDispatcher I provide to the Actor, right?

  5. Support Staff 5 Posted by Shaun Smith on 13 Dec, 2009 10:52 PM

    Shaun Smith's Avatar

    Yup, that's exactly how it'd be done.

  6. Joel Hooks closed this discussion on 14 Dec, 2009 05:41 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac