Skip to main content
AndrewZellman
Adobe Employee
Adobe Employee
August 5, 2009
Question

Using Async calls in a Util class

  • August 5, 2009
  • 2 replies
  • 3429 views

I have a Utility class that I want to put code in that I'm reusing over and over again.  This includes Async.handleEvent calls.  If I call an instance of the Util class from a [Test(async)] method, can I use the Async call in that other event?

When I tried this in my code, it said that it "Cannot add asynchronous functionality to methods defined by Test,Before or After that are not marked async" but my [Test] is marked as async. And when I was in the same class, I was able to have non-Test methods make Async calls.

Thanks for the help!

Mocked up Example (please note these are two separate files):

// Test.as

package

{

    import TimerUtil;

    public class Test

    {

        [Test(async)]
        public function waitForTimer():void

        {              

            TimerUtil.newTimer();
        }
    }

}

// TimerUtil.as

package

{

    import flash.events.TimerEvent;
    import flash.utils.Timer;

    import org.flexunit.async.Async;

    public class TimerUtil

    {

        private static var instance:TimerUtil;

        private var timer:Timer;
   
        private static const TIME_OUT:int = 1000;

        public static function newTimer() : void

        {

            if (!instance) instance = new TimerUtil();

            instance.timer = new Timer(1000, 5);

            instance.timer.start();

            instance.waitForFifthTick();

        }

        private function waitForFifthTick() : void

        {

            Async.handleEvent(this, instance.timer, TimerEvent.TIMER, handleTimerTick, TIME_OUT);

        }

        private function handleTimerTick ( evt:TimerEvent, eventObject:Object) : void

        {

            if ( timer.currentCount == 5 )

            {

                // We are at the Fifth click, move on.

            }

            else

            {

                Async.handleEvent(this, instance.timer, TimerEvent.TIMER, handleTimerTick, TIME_OUT);

            }

        }

    }

}

Message was edited by: zyellowman2 I missed a comma.  And a few "instance"s

This topic has been closed for replies.

2 replies

Participant
April 28, 2010

I've experienced similar problems when extending TestCase and using metadata annotations. Not extending TestCase fixes the problem.

Participating Frequently
May 6, 2010

You can't do both.

If you are extending TestCase then you are using FlexUnit 1 (.9) and it does not use metadata

If you do not extend TestCase and use metadata then you are using FlexUnit 4

Mike

Participating Frequently
August 5, 2009

Yes, you can put async calls in utility classes or wherever you want. That isn't the issue here though.

In your test you call TimerUtil.newTimer()

That code creates a timer and then returns. Then your test returns. At that moment, FlexUnit sees that your test has finished and that there are no outstanding registered asynchronous events so it declares the test a success. Then, a second later, your other method executes and tries to register an async call. FlexUnit has no idea what test this pertains to, or why this call is being made as it is no longer in the context of the original test, hence the message you are receiving that you can only using Async calls inside of a method marked with a Async... as, in FlexUnit's opion, the method that is executing this code no longer has anything to do with a test with an async param.

The best way to think about this is a chain that cannot be broken. As soon as a method finishes executing with, FlexUnit will declare it a success unless we are waiting on something else (an async event of some sort) That is what the Async syntax really does, it tells the framework not to declare this method a success just yet, and that there is something else we need to account for to make that decision.

So, right now, in your newTimer() you don't let the framework know that you will be waiting for an async event. Therefore, when that method and the test method is over, so is the test.

Mike

AndrewZellman
Adobe Employee
Adobe Employee
August 5, 2009

So is there a call I should make in that newTimer method, that would allow me to do it this way?

Participating Frequently
August 5, 2009

quickly looked at your issue. Looks like an async does get registered. Let me trace through this. Will get back to you today