Frage

Ich teste einen Code für den Ereignisversand in einer Flex-App mithilfe von FlexUnit addAsync Methode zum Testen, ob Ereignisse gesendet werden.Bisher großartig, ich kann sicherstellen, dass mindestens ein Ereignis ausgelöst wurde.Allerdings möchte ich etwas detaillierter darauf eingehen;Ich möchte sicherstellen, dass genau die von mir erwarteten Ereignisse ausgelöst werden.Gibt es ein nützliches Testmuster (oder sogar ein anderes Testframework – ich bin flexibel!), um dies zu erreichen?

Ich habe diesen Code ausprobiert, aber er scheint beim zweiten Mal nicht aufgerufen zu werden:

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);
}
War es hilfreich?

Lösung

Als Antwort auf den Kommentar ...

Was ist, wenn das Ereignis direkt versandt wird? Antworten ausgewählt werden nicht ein asynchrones Ereignis auf einem zusammengesetzten Objekt ausgelöst, sondern einfach das Response_Changed -Ereignis selbst entsandt. Ich sehe nicht, wie dieser Ansatz mit Ihrer Methode verspottet werden kann. Wohlgemerkt, ich bin verblüffend in der Mock-Testpraxis wie Is, also fehlt mir wahrscheinlich eine einfache Lösung hier.

In diesem Fall müssen Sie kein Mock oder Addasync verwenden. So etwas wird:

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

Andere Tipps

Dies wird ein allgemeines Beispiel dafür sein, wie ein ähnliches Problem mithilfe eines simulierten Objekts gelöst werden könnte, das den asynchronen Aufruf ausführt.Offensichtlich kann ich Ihren Code nicht sehen, daher kann ich Ihnen kein genaues Beispiel geben.

Wie ich im Kommentar sagte, können Sie also eine Abhängigkeit in einer Klasse nachahmen, um asynchrone Aufrufe vorzutäuschen, damit sie synchron werden.Nehmen Sie an der folgenden Klasse teil

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

Standardmäßig verwenden Sie also die konkrete Klasse, die Sie verwenden möchten, es sei denn, someAsynchronousObjec wird über den Konstruktor in die Klasse eingefügt.AsycnhronousObject verfügt wahrscheinlich über eigene Komponententests oder befindet sich in einer externen Klasse, sodass Sie seine Funktionalität nicht wirklich testen möchten oder müssen.Was Sie jetzt tun können, ist ein Scheinobjekt zu erstellen, das IAsynchronousObject implementiert, das verwendet werden kann, um sein Verhalten vorzutäuschen.Mit dem ASMock-Framework könnte der Test etwa so aussehen:

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

Dies ist nur ein Beispiel dafür, wie Mocking Ihnen bei Unit-Tests helfen kann.Es gibt eine ganze Fülle von Informationen zum Thema Mocking, obwohl es für ActionScript noch sehr neu ist (veröffentlicht im Dezember).ASMock basiert auf den .net-Rhino-Mocks, daher sollte die Suche nach Rhino-Mocks viel mehr Ergebnisse liefern, wenn Sie Hilfe benötigen.

Definitiv eine andere Denkweise, aber wenn man sich erst einmal damit beschäftigt, fragt man sich oft, wie man beim Unit-Testen ohne sie ausgekommen ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top