Skip to main content
May 11, 2010
Question

Async tests and Assert throws exceptions

  • May 11, 2010
  • 2 replies
  • 1578 views

Hi,

In a regular non-async test, something like Assert.assertEquals( "apples", "oranges" ); gives a nice report that the strings didn't match.  The test fails and the suite continues and all is good.  If the test is asynchronous, though, you get an uncaught exception, and a timeout on the test rather than a nice report.  Worse, it will cause a command-line based test to freeze with a stack trace showing (if you have a debug version of Flash, of course), until you hit the dismiss button.

Here's an example.  Without the Assert.assertEquals line, the test passes after two seconds as expected.  With the Assert.assertEquals in place, you get the behaviour I described.  So the question is, how do I use asserts in an asynchronous test?  I want the behaviour that you get with synchronous tests, i.e. a nice report and no pop-up dialog showing the stack.

        const TEST_COMPLETE:String = "testComplete";
        [Test(async)]
        public function myAsyncTest():void   
        {
            Async.proceedOnEvent( this, this, TEST_COMPLETE, 5000 );
            var t:Timer = new Timer(2000, 1);
            t.addEventListener(TimerEvent.TIMER, timeout);
            t.start();
        }
        private function timeout(e:Event):void
        {
            Assert.assertEquals( "apples", "oranges" );
            dispatchEvent( new Event(TEST_COMPLETE) );
        }

Any help?

Thanks!

DB

This topic has been closed for replies.

2 replies

May 11, 2010

Thanks for your reply.  It was helpful, but I'm still not out of the woods.  The timer example works nicely, with your adjustments.  Of course it was just a simple example of an asynchronous test.  I can't figure out how to get the real test reporting assertions correctly.

We have an asynchronous mechanism where we request a service and add a success handler callback and a fault (failure) callback.  So for example it might look like:


        token.addSuccessHandler( myTestSucceeded );
        token.addFaultHandler( myTestFailed );

...

        private function myTestFailed ( error:Error ):void

        {

            Assert.fail( "failed\n" + error.message );

        }

The mechanism I'm using always calls the fault handler with an Error parameter.  The Assert.fail line is one example of where I would like to use the standard Assert code and have results reported correctly.

The error object that is passed to the fault handler isn't known until the fault actually happens, so I can't provide it to Async.asyncHandler as the passThroughObject.  I can't think of a way to make this work.

Thanks again,

DB

Participating Frequently
May 29, 2010

There is an Async.asyncResponder method which returns a IResponder.

here is the signature:

public static function asyncResponder( testCase:Object, responder:*, timeout:int, passThroughData:Object = null, timeoutHandler:Function = null ):IResponder {

So, you can do something like this:

var responder:IResponder = Async.asyncResponder( this, new TestResponder( handleIntendedResult, handleUnintendedFault ), 50, someDataAlongforTheRide);

var token:AsyncToken = someCallThatReturnsMyToken();

token.addResponder( responder );

Mike

nikos101
Inspiring
December 23, 2010

Can I use AsyncResponder instead?

[Test(async)]
        public function testAttemptLogin():void
        {
            var token: AsyncToken = objectToTest.attemptLogin('sre','wd',);
            token.addResponder(new AsyncResponder(onResult, faultHandler));
        AsyncResponder
        }

Participating Frequently
May 11, 2010

The code you have below doesn't do what you think it does.

When you setup an async test in FlexUnit, it needs to know what code is related to a given test. When you use items like the asyncHandler() methods, it basically calls that code in a way that watches for assertions and can manage to track them when they occur.

In your code, you are setting up a timer and that timer is calling another method which does an assertion. The timer calls that code directly from the top of the call stack... in other words, completely outside of FlexUnit. FlexUnit doesn't know your method is being called and cannot wrap the call in order to catch any information thrown from your assertion.

Can you describe what you want to do and I can advise you on the right syntax? It isn't that assertions work differently in async tests, it is that FlexUnit has no idea that the timeout() method is being called, Flash Player is calling it directly, and hence there is no way for it to watch the assertion.

I am guessing you want something more alogn the lines of this, but I am not sure:

[

Test(async)]

public function myAsyncTest():void

{

var t:Timer = new Timer(2000, 1);

var handler:Function = Async.asyncHandler( this, timeout );

t.addEventListener(TimerEvent.TIMER, handler );

t.start();

}

private function timeout(e:Event, passThroughData:Object ):void

{

Assert.assertEquals(

"apples", "oranges" );

}