Search code examples
c#.netvisual-studio-2012windows-phone-8visual-studio-test-runner

Windows Phone 8 Unit Test creating a bitmapimage


I have a method that takes a BitmapImage.

I am trying to test it by creating or loading a BitmapImage and then passing it to said method.

However, unit test does not allow me to create a bitmapimage, it throws an InvalidCrossThreadException.

Is there any documentation or resource that details how to unit tests methods that take BitmapImages in Windows Phone 8.

We are using Visual Studio 2012 - update 2.


Solution

  • BitmapImage can only run on the UI thread, and the Unit-Test is running from a background thread. This is why you are getting this exception. For any tests involving BitmapImage or other UI component you'd need to:

    1. Push the UI work to the UI thread using Dispatcher.BeginInvoke()
    2. Wait for the UI thread to finish before completing the test.

    For example, using a ManualResetEvent (semaphore) to do the cross-thread signalling, and making sure that any (catchable) exceptions are passed back to the test thread...

    [TestMethod]
    public void TestMethod1()
    {
        ManualResetEvent mre = new ManualResetEvent(false);
        Exception uiThreadException = null;
    
        Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                try
                {
                    BitmapImage bi = new BitmapImage();
    
                    // do more stuff
                    // simulate an exception in the UI thread
                    // throw new InvalidOperationException("Ha!");
                }
                catch (Exception e)
                {
                    uiThreadException = e;
                }
    
                // signal as complete
                mre.Set();                    
            });
    
        // wait at most 1 second for the operation on the UI thread to complete
        bool completed =  mre.WaitOne(1000);
        if (!completed)
        {
            throw new Exception("UI thread didn't complete in time");
        }
    
        // rethrow exception from UI thread
        if (uiThreadException != null)
        {
            throw uiThreadException;
        }
    }