Using WPF components in NUnit tests - how to use STA?

13,221

Solution 1

Have you tried this?


... simply create an app.config file for the dll you are attempting to test, and add some NUnit appropriate settings to force NUnit to create the test environemnt as STA instead of MTA.

For convenience sake, here is the config file you would need (or add these sections to your existing config file):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="NUnit">
            <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
        </sectionGroup>
    </configSections>

    <NUnit>
        <TestRunner>
            <add key="ApartmentState" value="STA" />
        </TestRunner>
    </NUnit>
</configuration> 

Solution 2

You should add the RequiresSTA attribut to your test class.

[TestFixture, RequiresSTA]
public class MyTestClass
{
}

Solution 3

With more recent versions, the attribute has changed :

[Apartment(ApartmentState.STA)]
public class MyTestClass
{}
Share:
13,221

Related videos on Youtube

stiank81
Author by

stiank81

System Developer mainly living in the .Net-world. Coding in C#, Javascript, html, css, ..

Updated on June 10, 2020

Comments

  • stiank81
    stiank81 almost 4 years

    I need to use some WPF components in an NUnit unit test. I run the test through ReSharper, and it fails with the following error when using the WPF object:

    System.InvalidOperationException:

    The calling thread must be STA, because many UI components require this.

    I've read about this problem, and it sounds like the thread needs to be STA, but I haven't figured out how to do this yet. What triggers the problem is the following code:

    [Test]
    public void MyTest()
    {
        var textBox = new TextBox(); 
        textBox.Text = "Some text"; // <-- This causes the exception.
    }
    
    • Finglas
      Finglas over 14 years
      This isn't a unit test. Also, are you sure you want your tests to rely on WPF components? UI should be seperated from application logic for reasons such as the above.
    • stiank81
      stiank81 over 14 years
      Well - I'm aware that there isn't an actual test in here, and this isn't what my unit test look like. However - this is sufficient code for showing the point. Also - the problem is related to the fact that this is an nNnit unit test run through ReSharper - so I need to keep this context for the question. Your other point is valid though.. I don't want my unit tests to rely on WPF components, but for now this seems to be the best solution. Will see if I can get it out of there later..
    • stiank81
      stiank81 over 14 years
      If you want to see why I have UI in the application logic see my other question: stackoverflow.com/questions/2220842/…
    • cod3monk3y
      cod3monk3y over 9 years
      In a dynamic UI, such as with behaviors derived from System.Windows.Interactivity.Behavior<>, WPF extension methods (e.g. static void InsertUnder(this UIElementCollection, UIElement afterThis, UIElement toInsert)), layout manager code, dynamic data templating, and component authoring are a few example scenarios where writing unit tests which depend on WPF components is practical.
  • stiank81
    stiank81 over 14 years
    Thx! Just found the same solution myself, and it works. Apparently ReSharper uses an older version of nUnit, and therefore I can't simply use the [RequiresSTA] attribute.
  • bugged87
    bugged87 almost 9 years
    If a particular version of ReSharper has an issue with RequiresSTA, then why not just have ReSharper ignore that warning?
  • Michael Hohlios
    Michael Hohlios almost 8 years
    This is only for versions of NUnit below 3.0. It is obsolete > version 3.
  • Michael Hohlios
    Michael Hohlios almost 8 years
    This is the current answer with > version 3 of NUnit.
  • metal
    metal over 5 years
    Better solutions are below for different versions of NUnit, but they are not marked as the answer.
  • metal
    metal over 5 years
    I'd add that you can instead put the attribute on individual test functions to keep it isolated to where you actually need it. You can get into additional problems if you are testing async code where your test function has a signature like public async Task TestFunc(). In such cases in an MVVM world, you may want to inject a dispatcher dependency into your view model, use that internally for things manipulating view objects, and use it in your test likewise. This may even obviate the need for the Apartment attribute on the test assembly, class, test function.
  • Alan
    Alan over 4 years
  • datchung
    datchung over 4 years
    Works for me when declared on a class with [TestFixture, Apartment(ApartmentState.STA)] or on a method with [Test, Apartment(ApartmentState.STA)]
  • Tore Aurstad
    Tore Aurstad over 2 years
    I am using NUnit version 3.2.0 and I could not make this work by decorating only the method with [Apartment(ApartmentState.STA)]. I had to decorate the class with the attribute. Strange.