Sunday, January 10, 2010

Maximizing FlexUnit4 with Mocks and Closures

After spending the past few months using FlexUnit4 that comes with the new version of Adobe Flex called Flash Builder, I have a few tips on how to maximized your testing using mocks and closures. This comes as second nature for java/groovy/ruby programmers, but may be new to some in the Flex/Action Script community, so here goes.

Mocks: The project that I am currently on uses Swiz for IoC wiring and configuration of controllers, delegates, components, services and loggers. But, it's not good practice use IoC for tests, so we use mocks. Mocks that configure themselves, expose protected members, and reassign closures to methods that modify behavior for test purposes.

Example: The Shape factory: We have a factory class that generates various shapes such as lines, rectangles, ellipses, comment boxes, polylines, curves, etc. The method closure that creates specific shapes is called createShapeFromType. In the class constructor this closure is mapped to the factory's local private method createShape that creates and returns a shape object for the specified type. During some tests, this closure is mapped to createMockShape which returns a mock shape that can be tested independent of the factory. Other tests still use the mock factory but with the default createShape method in place to test and verify that it's behaving as expected. Think of it like a second level of polymorphism without having to create complex and ridged hierarchies (class bloat reduction).

MockShapeFactory: This mock extends ShapeFactory to inherit all of it's normal behaviour. So when I write a unit test against one of it's methods, I know that I'm exercising the real thing. But the mock allows me to keep track of what's going on inside the class as the tests run. And, the mock does it's own configuration mimicking what IoC performs in production.

MockShape: This mock has two primary purposes; 1) to configure itself for use, logs, delegates, etc, and 2) to expose protected methods and variables. For example, the shape has mouse event listeners that can be invoked through the test to see if the object moves to a specific set of coordinates. Or if it's a non-scaling shape, you can verify that the target shape performed a move an resize rather than a simple scaleX/scaleY operation. You can also test that a vetoed request for focus does indeed ignore the request and remain unfocused. There are many possibilities.

Some of this is very basic for test junkies, but as I said earlier, the Flex community seems to be just catching on to test driven development. And, with the new Flex/FlashBuilder and FlexUnit4 there is no excuse to ignore testing any longer.

No comments: