50

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.
}
Community
  • 1
  • 1
stiank81
  • 25,418
  • 43
  • 131
  • 202
  • 1
    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. – Finglas Feb 08 '10 at 09:50
  • 10
    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 Feb 08 '10 at 09:57
  • If you want to see why I have UI in the application logic see my other question: http://stackoverflow.com/questions/2220842/modifying-ui-from-commands-using-command-binding-in-wpf – stiank81 Feb 08 '10 at 10:23
  • 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. – cod3monk3y Feb 04 '15 at 00:37

3 Answers3

67

You should add the RequiresSTA attribut to your test class.

[TestFixture, RequiresSTA]
public class MyTestClass
{
}
Steven Muhr
  • 3,339
  • 28
  • 46
66

With more recent versions, the attribute has changed :

[Apartment(ApartmentState.STA)]
public class MyTestClass
{}
fbf
  • 711
  • 5
  • 5
  • 14
    This is the current answer with > version 3 of NUnit. – Michael Hohlios Jun 17 '16 at 20:17
  • 3
    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. – metal Dec 27 '18 at 16:07
  • Documentation is here https://github.com/nunit/docs/wiki/RequiresThread-Attribute – Alan Sep 02 '19 at 22:50
  • Works for me when declared on a class with `[TestFixture, Apartment(ApartmentState.STA)]` or on a method with `[Test, Apartment(ApartmentState.STA)]` – datchung Sep 06 '19 at 15:25
  • 1
    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. – Tore Aurstad Sep 10 '21 at 12:32
0

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> 
qujck
  • 14,388
  • 4
  • 45
  • 74
Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • 3
    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. – stiank81 Feb 08 '10 at 09:39
  • If a particular version of ReSharper has an issue with RequiresSTA, then why not just have ReSharper ignore that warning? – bugged87 Jul 22 '15 at 19:22
  • 1
    Better solutions are below for different versions of NUnit, but they are not marked as the answer. – metal Dec 27 '18 at 16:02