This is a quick post to share a solution to a problem I discovered while trying to unit some test some Flex code that involved states.
FormWithStates.as
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:states>
<mx:State name="advanced">
<mx:AddChild relativeTo="{nameItem}" position="after">
<mx:FormItem label="Age">
<mx:TextInput id="ageText"/>
</mx:FormItem>
</mx:AddChild>
</mx:State>
</mx:states>
<mx:Form width="100%">
<mx:FormItem id="nameItem" label="Name">
<mx:TextInput id="nameText"/>
</mx:FormItem>
<mx:FormItem>
<mx:Button label="Search"/>
</mx:FormItem>
</mx:Form>
</mx:HBox>
I was trying to reference the ageText component from my unit test like this:
FormWithStatesTest.as
package com.compact {
import flexunit.framework.TestCase;
public class FormWithStatesTest extends TestCase {
private var _view:FormWithStates;
override public function setUp():void {
_view = new FormWithStates();
_view.initialize();
}
public function testCanSetAgeText():void {
_view.ageText.text = "foo";
assertEquals("foo", _view.ageText.text);
}
}
}
Unfortunately every time I ran the test it would fail:

Null pointer exception. Ok thats because by default all the objects in an mxml state are created lazily. All we needed to do was to find a way to manually make sure my states are being initialized. I searched around the API for a while but failed to find anything obvious that would do the job. In the end I decided to do a bit of a hack and initialize all the components inside the state manually. This is what the end result looked like:
FormWithStatesTest.as
package com.compact {
import flexunit.framework.TestCase;
import mx.core.UIComponent;
import mx.states.IOverride;
import mx.states.State;
public class FormWithStatesTest extends TestCase {
private var _view:FormWithStates;
override public function setUp():void {
_view = new FormWithStates();
_view.initialize();
initializeStates(_view);
}
public function initializeStates(component:UIComponent):void {
for each (var _state:State in component.states) {
for each (var _override:IOverride in _state.overrides) {
_override.initialize();
}
}
}
public function testCanSetAgeText():void {
_view.ageText.text = "foo";
assertEquals("foo", _view.ageText.text);
}
}
}
Boom. Tests pass. I feel that since its a Friday afternoon I should celebrate, beer anyone?
I had a similar issue with tabbed controls, only this was causing problems at run time as well when I’m trying to programmatically access controls on tabs that were never viewed. The work around for my problem was to set the creation policy for the tabbed controls from auto to all. That might help you out in this sort of situation.