Unit testing in Silverlight part 3

Part 1
Part 2
Part 3
Part 4

This post continues on my previous two post on using the Microsoft Silverlight Unit Test Framework. You can find part 1 here and part 2 here.

In the second blog post I showed how to create a wrapper around the WebClient class, the TestableWebClient, so we can actually test code doing asynchronous web access. The part I didn’t really explain was the unit test itself. The unit test code looked likes this:

[TestClass]
public class FlickrDownloadTest : SilverlightTest
{
    [TestMethod]
    [Asynchronous]
    public void Test1()
    {
        FlickrRequest request = new FlickrRequest(typeof(MockTestableWebClient));

        request.PhotoSearchByUser("97044050@N00", (photo) => EnqueueTestComplete());
    }
    
    [TestMethod]
    [Asynchronous]
    public void Test2()
    {
        int pageCount = 0;
        FlickrRequest request = new FlickrRequest(typeof(MockTestableWebClient));

        request.PhotoSearchByUser("97044050@N00", (photo) => pageCount++);
        EnqueueConditional(() =>
            {
                return pageCount == 5;
            });
        EnqueueTestComplete();
    }
}


There are a couple of things to note here. First of all the test class derives from a base class SilverlightTest. This SilverlightTest enabled all sorts of interesting new things like a TestPanel for doing user interface testing. In this case we are interested in the support for asynchronous behavior and that is included in the WorkItemTest class, one of the parents of the SilverlightTest class.



The second thing to note is that each test is decorated with the Asynchronous attribute. This tells the Silverlight Unit Test Framework that the test isn’t done when the method is finished but some asynchronous actions is taken. So when is the test finished? Well as soon as the EnqueueTestComplete() function is called. In the first test this is done as soon a a photo is downloaded in the PhotoSearchByUser() function. The second test does a bit of extra work. It counts the number of photo’s downloaded, the same as the number of pages in this test. The test checks the number of pages downloaded using the EnqueueConditional() call. This EnqueueConditional() takes a lambda expression and waits for the expression to be valid. In this case the test is for the number of pages downloaded. Only when the condition is met do we move on to the next queued command, in this case the EnqueueTestComplete() to indicate that the test is done.



Besides the two methods used so far, the EnqueueTestComplete() and the EnqueueConditional() there are a number of other methods you can use to fine tune the test behavior. The EnqueueCallback() function can be used to add any code to the test queue. Use this to do Assert calls to validate the state of the test. The EnqueueDelay() is another useful function, specially when doing UI testing, to make sure different queued callbacks are not executed to quickly after each other.



Conclusion



The asynchronous testing capability is a great addition to the standard testing capabilities. In normal unit test the same behavior can be achieved using an AutoResetEvent object but this takes more work so it is nice to see that all the plumbing is taken care of [:)].



Enjoy!



 



Update: Part 1, Part 2, Part 3.



 



[f1]
[f2]

One thought on “Unit testing in Silverlight part 3

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>