« Silverlight PivotViewer and SharePoint | Main | Silverlight first asynchronous test run twice »
Wednesday
Jul072010

Silverlight Unit Testing - adding a timeout to EnqueueConditional

Since a lot of Silverlight work is asynchronous in nature, the Silverlight testing framework has many helper functions to essentially do "non blocking wait until something happens"

The curious one to me is EnqueueConditional(Func<bool> conditionalDelegate

This one essentially waits until the condition is true - so you can call a method to populate your view model with data, and then wait until data.Count > 0

But the method has no support for timeout.  It can, and will, hold the unit testing framework in progress forever.

Here's my little tweak to the method.

        public override void EnqueueConditional(Func<bool> conditionalDelegate)
        {
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 5);
            timer.Tick += delegate
            {
                // remember to stop timer or it'll tick again
                timer.Stop();
                throw new TimeoutException();
            };
            EnqueueCallback(delegate
            {
                timer.Start();
            });
            base.EnqueueConditional(conditionalDelegate);
            EnqueueCallback(delegate
            {
                timer.Stop();
            });
        }

Here's the unit test to go with it

        [TestMethod]
        [TestProperty("TestCategory", "Silverlight")]
        [Asynchronous]
        [ExpectedException(typeof(TimeoutException))]
        public void Test_Timeout()
        {
            EnqueueConditional(delegate
            {
                // return?  never!
                return false;
            });

            EnqueueTestComplete();
        }

And one more tweak in the App.xaml.cs

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is TimeoutException)
            {
                e.Handled = true;
                // stop any timeoutexception here or it'll bubble to the DOM
                return;
            }

            ...
        }

Here's the result picture:  Running just slightly over 5 seconds.

image

 

Updated: added a result picture.

Reader Comments (3)

Interesting work-around...

You should also check out the TimeoutAttribute...

namespace Microsoft.VisualStudio.TestTools.UnitTesting
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class TimeoutAttribute : Attribute
}

You can see an example of it here.
http://github.com/staxmanade/StatLight/blob/master/src/StatLight.IntegrationTests.Silverlight.MSTest/MSTestTests.cs#L81

July 9, 2010 | Unregistered CommenterJason

wow... im kind of confused... im just learning those things and im getting confused very fast...
any other tips?

July 12, 2010 | Unregistered Commenterunit testing tool

not sure what kind of examples or where you are getting confused. I have one more blog post about refactoring Silverlight to MVVM that's still in drafts.

July 12, 2010 | Registered CommenterJohnLiu.NET

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>