2009-07-22 6 views
3

Je teste un code d'expédition d'événement dans une application Flex, en utilisant la méthode addAsync de FlexUnit pour tester que les événements sont distribués. Génial jusqu'ici, je peux m'assurer qu'au moins un événement a été déclenché. Cependant, je veux être un peu plus détaillé. Je veux m'assurer que l'ensemble des événements auxquels je m'attends est exactement distribué. Existe-t-il un modèle de test utile (ou même un cadre de test différent - je suis flexible!) Pour y parvenir?Flex, Flexunit: Comment tester qu'un événement est envoyé deux fois?

J'ai essayé ce code, mais il ne semble pas s'invoquer la deuxième fois:

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); 
} 
+0

Vous pouvez presque certainement se débarrasser de l'addAsync en utilisant ASMock (http://asmock.sourceforge.net/) pour se moquer de tout ce qui est fait les appels asynchrous à requiredQuestion. Une fois que vous vous débarrasserez de l'addAsync, tout fonctionnera de manière synchrone. Va arriver avec un exemple demain matin (Royaume-Uni) s'il n'y a toujours pas de réponse. J –

Répondre

2

En réponse au commentaire ...

si l'événement est distribué directement? responseSelected ne déclenche pas un événement asynchrone sur un objet composite , il a simplement envoyé directement l'événement RESPONSE_CHANGED lui-même . Je ne vois pas comment cette approche peut être moquée en utilisant votre méthode . Rappelez-vous, je suis floue sur la pratique de test de simulation tel quel, donc je suis probablement manquant une solution simple ici.

.. dans ce cas, vous n'avez pas besoin d'utiliser un simulateur ou addAsync. Quelque chose comme cela va faire:

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); 
} 
2

Cela va être un exemple de haut niveau de la façon dont un problème similaire pourrait être résolu en utilisant un émulés objet de quoi que ce soit qui fait l'appel asynchrone. Évidemment, je ne peux pas voir votre code, donc je ne peux pas vous donner un exemple précis. Donc, comme je l'ai dit dans le commentaire, vous pouvez simuler une dépendance dans une classe pour simuler des appels asynchrones afin qu'ils deviennent synchrones. Prenez la classe ci-dessous

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)); 
    } 
} 

donc par défaut que vous utilisez la classe concrète que vous voulez utiliser, à moins someAsynchronousObjec est injecté dans la classe par le constructeur. AsycnhronousObject a probablement ses propres tests unitaires ou est dans une classe externe donc vous ne voulez pas vraiment, ou devez tester ses fonctionnalités. Ce que vous pouvez maintenant faire est de créer un objet fantaisie qui implémente IAsynchronousObject qui peut être utilisé pour simuler son comportement. En utilisant le cadre de ASMock le test pourrait ressembler à ceci:

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(); 
} 

Ceci est juste un exemple de la façon dont se moquant peut vous aider à des tests unitaires. Il y a toute une mine d'informations sur la moquerie, bien qu'il soit encore très nouveau pour ActionScript (sorti en décembre). ASMock est basé sur les modèles .net Rhino, donc la recherche de faux-semblants devrait donner beaucoup plus de résultats si vous avez besoin d'aide. C'est une manière de penser différente, mais une fois que vous y êtes entré, vous avez tendance à vous demander comment vous vous êtes débrouillé dans les tests unitaires sans eux.

+0

Que faire si l'événement est envoyé directement? responseSelected ne déclenche pas d'événement asynchrone sur un objet composite, il a simplement envoyé directement l'événement RESPONSE_CHANGED lui-même. Je ne vois pas comment on peut se moquer de cette approche en utilisant votre méthode.Rappelez-vous, je suis flou sur la pratique des tests simulés tel qu'il est, donc je manque probablement une solution simple ici. –

Questions connexes