Test : Using a brush in an async method

0
public class UnitTest1
{
    // you cant use a brush because it is UI
    // you switch to a UI test and it fails because it is async
    // bottom line you cant test an async routine that uses a brush,
    // even though your really are not doing ANY UI stuff - how stupid is that?

    [TestMethod]
    //[Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AppContainer.UITestMethod]
    async public Task TestMethod1()
    {
        var t = new ObservableCollection<CommentEvent>();
        t.Add(new CommentEvent(Colors.LightPink) { Label = "Bad", 
              EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
              TimeCode.SmpteFrameRate.Smpte2997Drop) });
        t.Add(new CommentEvent(Colors.DarkSeaGreen) { Label = "Good",
               EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
               TimeCode.SmpteFrameRate.Smpte2997Drop) });
        t.Add(new CommentEvent(Colors.LightPink) { Label = "Bad",
               EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
               TimeCode.SmpteFrameRate.Smpte2997Drop) });
        t.Add(new CommentEvent(Colors.DarkSeaGreen) { Label = "Good",
               EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
               TimeCode.SmpteFrameRate.Smpte2997Drop) });

        var s = await PreludeXMP.Get(t);

        Assert.IsNotNull(s);
        System.Diagnostics.Debug.WriteLine(s);
    }
}

this throws a

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD)). If you are using UI objects in test consider using [UITestMethod] attribute instead of [TestMethod] to execute test in UI thread.

Because the constructor for CommentEvent creates a Solid.Brush. Any suggested workaroundsarounds?

c#
windows-8.1
asked on Stack Overflow Nov 17, 2013 by Spiked3 • edited Nov 17, 2013 by Noctis

1 Answer

0

I encountered a very similar issue when trying to use WriteableBitmap along with an asynchronous method in one of my tests. While searhing for a way to make it work, I stumbled upon your question and chue x's answer mentioned the comments.

Using his approach I managed to make it work even with asynchronous calls. In your case the test code could be modified like this:

[TestMethod]
async public Task TestMethod1()
{
    var taskSource = new TaskCompletionSource<object>();
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
        CoreDispatcherPriority.Normal, async () =>
    {
        try
        {
            var t = new ObservableCollection<CommentEvent>();
            t.Add(new CommentEvent(Colors.LightPink) { Label = "Bad", 
                  EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
                  TimeCode.SmpteFrameRate.Smpte2997Drop) });
            t.Add(new CommentEvent(Colors.DarkSeaGreen) { Label = "Good",
                   EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
                   TimeCode.SmpteFrameRate.Smpte2997Drop) });
            t.Add(new CommentEvent(Colors.LightPink) { Label = "Bad",
                   EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
                   TimeCode.SmpteFrameRate.Smpte2997Drop) });
            t.Add(new CommentEvent(Colors.DarkSeaGreen) { Label = "Good",
                   EventTime = TimeCode.FromTicks(DateTime.Now.Ticks,
                   TimeCode.SmpteFrameRate.Smpte2997Drop) });

            var s = await PreludeXMP.Get(t);

            Assert.IsNotNull(s);
            System.Diagnostics.Debug.WriteLine(s);

            askSource.SetResult(null);
        }
        catch (Exception e)
        {
            taskSource.SetException(e);
        }
    }
    await taskSource.Task;
}

I've written a more in depth explanation with my own example in a blog post that I've just published.

answered on Stack Overflow Dec 9, 2013 by Damir Arh • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0