4 Replies Latest reply: Dec 23, 2010 3:46 AM by nikos101 RSS

    Async tests and Assert throws exceptions

    Icantfindanavailablename Community Member

      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

        • 1. Re: Async tests and Assert throws exceptions
          Michael Labriola Community Member

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

          }

           

          • 2. Re: Async tests and Assert throws exceptions
            Icantfindanavailablename Community Member

            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

            • 3. Re: Async tests and Assert throws exceptions
              Michael Labriola Community Member

              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

               

               

              • 4. Re: Async tests and Assert throws exceptions
                nikos101 Community Member

                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
                        }