8 Replies Latest reply: Jan 7, 2011 2:04 AM by nikos101 RSS

    Testing states in FlexUnit4

    Ignacio Martín Prieto Community Member

      Hi,

       

      I'm trying to test a component that has a Skin with 2 states, this skin contains a Button (btnMyButton) with "includeIn='state1'" and a TextInput (txtMyText) with "includeIn='state2'".

       

      Clicking on the button triggers a method that changes the state, the problem is when I try to access the TextInput on the next step, I get a null pointer. It seems like the property that defines the state of the skin (myComp.skinState) has been updated properly, but the actual skin has not been updated and my TextInput has not been added to the stage. Does anyone know what the correct way for doing this is? Am I doing anything wrong?

       

      See my code below.

       

      Thanks.

       

      - MyCompTest.as

       

           [Before( async, ui )]
            public function setUp() : void
            {
               myComp = new MyComp();
               myComp.setStyle( "skinClass", MyCompSkin );
               Async.proceedOnEvent( this, myComp, FlexEvent.CREATION_COMPLETE );
               UIImpersonator.addChild( myComp );
            }

       

           [Test( async, ui )]
            public function testOpenCloseMenu() : void
            {
               Async.handleEvent( this, myComp.btnMyButton, MouseEvent.CLICK, handleClickEvent, 500 );
               myComp.btnMyButton.dispatchEvent( new MouseEvent( MouseEvent.CLICK ));
            }

       

           protected function handleClickEvent( event : Event, passThroughData : Object ) : void
            {
               Assert.assertEquals( "1-The state is incorrect", "open", myComp.skinState );             // skinState has the correct value, but myComp.skin.currentState hasn't
               Async.handleEvent( this, myComp.txtMyText, MouseEvent.ROLL_OUT, handleRollOutEvent, 500 );
               myComp.txtMyText.dispatchEvent( new MouseEvent( MouseEvent.ROLL_OUT ));        // txtMyText is null at this point!
            }
          
            protected function handleRollOutEvent( event : Event, passThroughData : Object ) : void
            {
               Assert.assertEquals( "2-The state is incorrect", "closed", myComp.skinState );
            }

       

       

      - MyComp.as

       

           override protected function getCurrentSkinState() : String
            {
               return skinState;
            }

        • 1. Re: Testing states in FlexUnit4
          Michael Labriola Community Member

          There are exceedingly few things in the Flex framework that are synchronous. For almost everything in the component lifecycle, updating properties, creating children and, I am sure, states, things are going to be asynchronous. When you are creating the button, you are waiting for creationComplete, which is good. My guess is that after you rollout, you likely need to wait for another even indicating that the state has changed before you try to do your assert.

           

          Right now your assert is happening synchronously, meaning you issue a rollout and immediately expect the state to have chnaged and everything to have updated. That is likely not a reasonable expectation in Flex.

           

          Mike

          • 2. Re: Testing states in FlexUnit4
            Ignacio Martín Prieto Community Member

            Hi Mike,

             

            I did try listening for other events dispatched by the flex framework like FRAME_ENTER or FRAME_EXIT and some others. None of them seemed to work as the skin state had not been updated at that point. I have done some research but I haven´t found any event that gets dispatched after a display update. Any ideas of what event could it be?

             

            Thanks,

            Ignacio

            • 3. Re: Testing states in FlexUnit4
              Ignacio Martín Prieto Community Member

              I found FlexEvent.UPDATE_COMPLETE useful in case anyone is interested:

               

              Async.handleEvent( this, myComponent, FlexEvent.UPDATE_COMPLETE, handleStateChange, 1000 );

               

              I was also able to listen to the currentStateChange event on the skin, but I coudn´t do it twice in the same test like this:

               

                      [Test(async,ui)]
                      public function testOne() : void
                      {
                          Async.handleEvent( this, myComponent, StateChangeEvent.CURRENT_STATE_CHANGE, handleStateChange, 1000 );
                          component.btnSubmit.dispatchEvent( new MouseEvent( MouseEvent.CLICK ) ); // this triggers the state change
                      }
                     
                      protected function handleStateChange( event : Event, param : * ) : void
                      {
                          Assert.assertEquals( "Something went wrong", "state2", myComponent.skin.currentState );

                          Async.handleEvent( this, myComponent, StateChangeEvent.CURRENT_STATE_CHANGE, handleStateChange2, 1000 );
                           component.btnSubmit.dispatchEvent( new MouseEvent( MouseEvent.CLICK ) ); // this triggers the state change
                      }

               

                      protected function handleStateChange2( event : Event, param : * ) : void
                       {
                           Assert.assertEquals( "Something went wrong", "state2", myComponent.skin.currentState );
                       }

               

              I got a timeout on the second wait when I tried that.

               

              Any ideas?

               

              Thanks,

              Ignacio

              • 4. Re: Testing states in FlexUnit4
                davorian

                You have two timeouts of 1000 but the test method  testOne has a test metadata tag with no timeout attribute on it try 2000. I think this thus defaults to 500. So your second Async can occur after the method timesout.

                • 5. Re: Testing states in FlexUnit4
                  rduclos56

                  @Ignacio: Did you ever figure out the timeout issue? I recreated this example was able to run both tests in under .2s so I don't think setting the timeout variable any higher would solve this.

                   

                  -Created a component with 2 skin parts, button and textinput

                  -Created a skin for that component that had the button only in btnState and textInput in textInput State only

                  -Created handler functions for a click event on the button and a roll_over on the textInput, that would set the skin's current state as well as dispatch a custom flash event called skinStateChange

                  -Also over rode the partAdded and partRemoved functions, adding listeners to the button and textinput for the click and rollover events.

                   

                  -Created two tests, one to test the button skin state and one for the textinput skin state.

                  - - - First test since the component's skin starts in the button state, I had the component listen for the skinStateChange event, and used an Async handler to call a function that tested if the skins current state equaled the a string that was set to what state it should be in, which in this case should be in textInputState since the button is being clicked.  Had the button dispatch a Click event.

                   

                  --Second test is pretty much the same, but need to set the skin's current state to textInputState first, so the textinput can be created as well as allowing us to test the change of states to the button state, and that the textinput will be dispatching a roll_over event instead of a click event.

                   

                  Let me know if you have any questions or want to see any of the code.

                  • 6. Re: Testing states in FlexUnit4
                    nikos101 Community Member

                    so can you run both aysnc tests in order? Any of you have any ideas how I can test a button that for some weird reason is dispatching multiple click events randomly?

                    • 7. Re: Testing states in FlexUnit4
                      rduclos56 Community Member

                      @Nikos - Hey, sorry it's been awhile, but let me see if I can help out at all. The tests are run independently of eachother, and what I mean by this is the second test is not relying on what is happening from the first test. So make sure you have all your preconditions set before running the test. Do not make tests dependent on eachother!

                       

                      As to your second point, without seeing code I have no idea why your button is dispatching multiple click events randomly ;p

                       

                      Also I might recommend opening a new topic since this one is a bit old, also if you need any more info on Flexunit check out the wiki.

                       

                      http://docs.flexunit.org/index.php?title=Main_Page

                      • 8. Re: Testing states in FlexUnit4
                        nikos101 Community Member

                        Thanks mate, my problems have been solved in the meantime