Flex、FlexUnit:イベントが2回発送されることをテストする方法は?
-
19-09-2019 - |
質問
FlexUnitを使用して、Flexアプリでいくつかのイベントディスパッチコードをテストしています addAsync
イベントをテストする方法が発送されます。これまでのところ、少なくとも1つのイベントが解雇されたことを確認できます。しかし、私はもう少し詳細になりたいです。私が予想している一連のイベントが派遣されていることを確認したいと思います。これを達成するために、有用なテストパターン(または、さまざまなテストフレームワーク - 私は柔軟です!)はありますか?
このコードを試しましたが、2回目に呼び出されていないようです。
protected function expectResultPropertyChange(event: Event, numberOfEvents: int = 1): void {
trace("Got event " + event + " on " + event.target + " with " + numberOfEvents + " traces left...");
assertTrue(event.type == ResponseChangedEvent.RESPONSE_CHANGED);
if (numberOfEvents > 1) {
event.target.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, addAsync(expectResultPropertyChange, 1000, numberOfEvents - 1));
}
}
public function testSomething(): void {
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, addAsync(expectResultPropertyChange, 1000, 2));
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
}
解決
コメントに応じて...
イベントが直接発送された場合はどうなりますか? ResponseSelectedは、複合オブジェクトで非同期イベントをトリガーしません。これは、Response_Changedイベント自体を直接発送するだけです。このアプローチがあなたの方法を使用してどのようにock笑できるかはわかりません。気をつけて、私は模擬テストの練習であいまいなので、おそらくここで簡単な解決策を見逃しているでしょう。
..その場合、模擬またはaddasyncを使用する必要はありません。このようなことは次のとおりです。
public function testSomething(): void
{
var requiredQuestion : RequiredQuestion = new RequiredQuestion();
var callCount : int = 0;
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, function(event : ResponseChangedEvent)
{
callCount++;
});
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
assertEquals(2, callCount);
}
他のヒント
これは、非同期呼び出しを行っているもののモックアウトされたオブジェクトを使用して、同様の問題をどのように解決できるかの高レベルの例になるでしょう。明らかに私はあなたのコードが見えないので、正確な例を挙げることはできません。
だから、私がコメントで言ったように、あなたはクラスの依存関係を模倣して非同期呼び出しを偽造して、それらが同期するようにすることができます。以下のクラスを取ります
public class RequiredQuestion extends EventDispatcher
{
private var someAsynchronousObject : IAsynchronousObject;
public function RequiredQuestion(someAsynchronousObject : IAsynchronousObject = null)
{
someAsynchronousObject = someAsynchronousObject || new AsynchronousObject();
someAsynchronousObject.addEventListener(Event.COMPLETE, asyncCallComplete);
}
public function responseSelected(id : String, flag : Boolean) : void
{
//Will asynchronously fire the Event.COMPLETE event
someAsynchronousObject.startAsynchrounsCall();
}
protected function asyncCallComplete(event : Event) : void
{
dispatchEvent(new ResponseChangedEvent(ResponseChangedEvent.RESPONSE_CHANGED));
}
}
したがって、デフォルトでは、Someasynchronousobjecがコンストラクターを介してクラスに注入されない限り、使用するコンクリートクラスを使用しています。 AsycnhronousObjectには、おそらく独自の単体テストがあるか、外部クラスにあるため、機能を実際に望んでいないか、その機能をテストする必要がありません。今できることは、その動作を偽造するために使用できるIasynchronousObjectを実装する模擬オブジェクトを作成することです。 Asmockフレームワークを使用して、テストは次のようになります。
public function testSomething(): void
{
var mockIAsycnhronousObject : IAsynchronousObject =
IAsynchronousObject(mockRepository.createStrict( IAsynchronousObject));
SetupResult.forEventDispatcher(mockIAsycnhronousObject);
SetupResult.forCall(mockIAsycnhronousObject.startAsynchronousCall())
.dispatchEvent(new Event(Event.COMPLETE)); // all calls to the startAsynchronousCall method and dispatch the complete event everytime it's called.
mockRepository.replayAll();
var requiredQuestion : RequiredQuestion = new RequiredQuestion(mockIAsycnhronousObject);
var callCount : int = 0;
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, function(event : ResponseChangedEvent)
{
callCount++;
});
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
assertEquals(2, callCount);
mockRepository.verifyAll();
}
これは、モッキングがユニットテストにどのように役立つかの例のほんの一例です。 ActionScript(12月にリリース)にとってはまだ非常に新しいものですが、モッキングには豊富な情報があります。 Asmockは.NET Rhino Mocksに基づいているため、Rhino Mocksを検索することで、サポートが必要な場合はさらに多くの結果が発生するはずです。
間違いなく別の考え方ですが、一度それに入ると、あなたは彼らなしでのユニットテストでどうやって手に入れたのか疑問に思う傾向があります。