WPF and MSTest
This post demonstrates a solution for overcoming the exception that is thrown when trying to test a WPF class with MSTest.
Problem
I was recently trying to run a unit test containing a WPF class and received the following error during test execution: "System.InvalidOperationException: 'The calling thread must be STA, because many UI components require this.'" This exception was thrown when I tried to instantiate a class that was derived from System.Windows.Controls.UserControl
. It's complaining because only STA threads can create those types of classes and my unit test isn't an STA thread.
I did some Googling and just about every result that appeared was for NUnit, but I'm using MSTest (MSTest.TestFramework), so I needed a solution for that framework specifically.
Solution
The solution was actually really simple when I found this link. I created a WpfTestMethodAttribute
class and then applied it to my unit tests.
Here's the WpfTestMethodAttribute
. It is used instead of the normal TestMethodAttribute
that MSTest provides.
public class WpfTestMethodAttribute : TestMethodAttribute
{
public override TestResult[] Execute(ITestMethod testMethod)
{
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
return Invoke(testMethod);
TestResult[] result = null;
var thread = new Thread(() => result = Invoke(testMethod));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return result;
}
private TestResult[] Invoke(ITestMethod testMethod)
{
return new[] { testMethod.Invoke(null) };
}
}
Here's a quick and dirty example of the attribute in use.
[TestClass]
public class MyTestClass
{
[WpfTestMethod]
public void MyWpfTest()
{
// The following line will fail unless executed on an STA thread.
var userControl = new UserControl();
Assert.IsNotNull(userControl);
}
}