Testing of actionscript code is not very useful if your tests can’t wait for and react to events. Flexunit is the main unit testing framework for Flex and it has some nice tools for setting up asynchronous tests.
The code I’m testing for this example comes from the Swiz Cafe Townsend project. Swiz has its own unit testing framework to go along with flexunit, but I’m not going to use it here. It does not appear to be updated to run with the latest version of flexunit (though calling
constructSwizContext() in your own test class’s
[Before]-annotated method fixes the main issue).
More importantly, though, using a dependency injection framework like Swiz in your unit tests means having to set up all the relevant dependencies and tying your tests to the framework. You’re testing not just your target methods but also your Swiz configuration. That’s great for integration tests, but here I want my unit tests to just test the methods’ functionality. Therefore I’ll manually create the objects that Swiz injects in the production system.
The code under test is the
updateEmployee() method in
EmployeeDetailPresentationModel, which basically dispatches an update event for an employee. I’m testing both for the event dispatch and for correct employee values.
Async.handleEvent can be used to listen for the event and to provide a result method that will be called when the event is registered.
Here is the test:
I’m adding this test to
com.cafetownsend.presentation.test.EmployeeDetailPresentationModelTest in Cafe Townsend, and making use of its existing setup. Before each test, it creates a basic employee, defines a presentation model, and importantly, creates a new dispatcher for the model. When the application actually runs, Swiz will inject that dispatcher, but for a test we can just create a plain old
handleEvent, we pass in the test itself, the dispatcher, the event we’re listening for (
EmployeeEvent.UPDATE), the method to call when the event is detected (
verifyUpdate), the max time we’ll wait for the event (500 ms), the ‘passThroughObject’ (employee), and the method to call if the time-out is reached (
dispatchingEventNeverOccurred). The call to
updateEmployee() is what all the set up has been for and what kicks things off.
handleEvent parameters are pretty straightforward except for the passThroughObject. This is an object containing data from the test that you can pass through to your result handler (
verifyTest) in order to make assertions. It’s easier when you see verifyTest:
The employee object we created in the first part of our test is passed through as the second argument tp
verifyTest, and we can use it to check if expected changes took place somewhere else in the code, in this case, the model’s tempEmployee. The passThroughObject is just a convenient way to preserve information from the beginning of the test for assertions at the end.
Looking a little more at Swiz Cafe Townsend’s
EmployeeDetailPresentationModelTest, there are already tests like
dispatchUpdateEvent, which makes sure that when
updateEmployee() is called, the appropriate event is thrown. If all you need to test is that an event is dispatched but aren’t worried about checking data, all you need is
Async.proceedOnEvent() with a timeoutHandler that includes an
Assert.fail() if it actually gets called, ie. the test times out without registering the expected event.
Another useful trick in Flexunit is using the asyncResponder to add a result handler to a service call, but that will have to wait until later.