.NET

Using a SynchronizationContext in unit tests

We’ve started to use the Progress<T> class in our async application. However our tests started to fail because of that (when validating that our callbacks get invoked). This post will show you how to create a simple 

SynchronizationContext
to make sure that everything is invoked before the assert part is being run.

If you google around you’ll see a couple of articles that demonstrate how you can create a custom context for your tests. They do however require that you manually modify each test to be able to guarantee that all tasks have been invoked.

For unit tests the solution is much more simple in most cases. Simply create a context which invokes the delegates directly:

public sealed class TestSynchronizationContext : SynchronizationContext
{
    public override void Post(SendOrPostCallback d, object state)
    {
        d(state);
    }
    public override void Send(SendOrPostCallback d, object state)
    {
        d(state);
    }
}

Next you need to init it in some way. According to the MSDN documentation you can create a single class with a single method that will be run before each test:

[TestClass]
public class TestAssemblyInitializer
{
    [AssemblyInitialize]
    public static void Init(TestContext context)
    {
        SynchronizationContext.SetSynchronizationContext(new TestSynchronizationContext());
    }
}

Unfortunately that doesn’t work, for me it’s just run once. The real solution is to add an init method to each test class:

[TestClass]
public class ActionPlanExecutionServiceTests
{
    [TestInitialize]
    public void Init()
    {
        SynchronizationContext.SetSynchronizationContext(new TestSynchronizationContext());
    }
    //[... your test methods ..]
}

Once done, all your tests that are depending on a synchronization context should now be green.

Related Articles

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button