flexunitのTestCase::addAsync()の罠
非同期処理のテストを行う場合、
dispatcher.addEventListener(Event.COMPLETE, addAsync(onComplete), 1000));
という感じでイベントハンドラのメソッドを addAsync でラップするのですが、この手のテスト中にはまってしまったことをメモ。
public function testDispatcher():void { var dispatcher:MyEventDispatcher = new MyEventDispatcher(); dispatcher.addEventListener(Event.COMPLETE, addAsync(onRestoreComplete), 1000)); // loader の型は Loader dispatcher.loader.addEventListener(Event.COMPLETE, addAsync(onLoadComplete), 1000)); } // onRestoreComplete より先に呼ばれる private function onLoadComplete(event:Event):void { var loader:Loader = Loader(event.target); : } // onLoadComplete より後で呼ばれる private function onRestoreComplete(event:Event):void { var dispatcher:MyEventDispatcher = MyEventDispatcher(event.target); : }
こんな感じのテストコードを実行したところ、
var dispatcher:MyEventDispatcher = MyEventDispatcher(event.target);
の部分で強制型変換のエラーが出ました。
内容は、Loader を MyEventDispatcher へキャストできないと。
通常のイベントの処理だと問題無いはずが、なぜ...?
ということでいろいろ試してみたんですが、どうやら onLoadComplete と onRestoreComplete の event.target にはどちらも dispatcher.loader が設定されている模様...。
試しにテストメソッドを分けてみたらうまくいきました。
// テストメソッド1 public function testDispatcher1():void { var dispatcher:MyEventDispatcher = new MyEventDispatcher(); dispatcher.loader.addEventListener(Event.COMPLETE, addAsync(onLoadComplete), 1000)); } private function onLoadComplete(event:Event):void { var loader:Loader = Loader(event.target); : } // テストメソッド2 public function testDispatcher2():void { var dispatcher:MyEventDispatcher = new MyEventDispatcher(); dispatcher.addEventListener(Event.COMPLETE, addAsync(onRestoreComplete), 1000)); } private function onRestoreComplete(event:Event):void { var dispatcher:MyEventDispatcher = MyEventDispatcher(event.target); : }
どうも1つのテストメソッドで2回 addAsync を使うと、呼ばれるイベントハンドラの引数が狂うみたいです。
flexunitの仕様なのか、バグなのかは不明です。
気をつけよっと。