NUnit STA Threads & Testing WPF

During the course of the WPF project we are working on at work, we decided to go down the Agile/XP/TDD/Mocks/Continuous Integration route, which means Unit tests, lots of them.

We are using NUnit, which I really like, but we are also using WPF, we are obviously using the latest/greatest patterns AKA MVVM, but from time tom time it is nice to be able to test certain things on WPF controls/windows etc etc.

So I set out to create a small NUnit test like the following:


diag11.jpg

Now to me this looked fine, but when I ran this code I got the following horror show.

STAThread

Where NUnit moaned about “The calling thread must be STA”. Oh, that’s to bad. So I had a small think, and then came up with this small idea, just pass the original code to a helper class and have it run that in a Thread using STA threading apartment state. Sounds cool, but did it work. Well yes actually it did, and here is the small helper class.

 

 diag2.jpg


And here is how to use this from a NUnit test.


diag3.jpg

And just to prove it works, here is a screen shot of the actual test running successfully.

STAThreadOK

Here is a link to a small test project that you can see this working with : wpfandnunittest1.zip in case you want to use this in your own projects.

Enjoy

17 Comments so far »

  1. Josh Smith said

    am November 18 2008 @ 9:08 pm

    Nice job man. I wrote about this topic a while back, in case you’re interested: http://www.codeproject.com/KB/WPF/UnitTestDispatcherTimer.aspx

    Josh

  2. sacha said

    am November 18 2008 @ 10:03 pm

    Doh, I even left a comment on that article you wrote, must have forgot about that. Oh well proves we are both cool, I guess.

  3. daniel sun said

    am November 19 2008 @ 12:53 am

    there is problem with this, here is an example:
    add the following to class UserControl1
    private string foo;
    public String Foo
    {
    get
    {
    return “foo”;
    }
    set
    {
    foo = value;
    }
    }
    add the following test to class UserControlTests
    [Test]
    public void TestFoo()
    {
    ThreadExecutor.RunCodeAsSTA(
    delegate
    {
    WpfAndNUnitTest.UserControl1 uc1 = new WpfAndNUnitTest.UserControl1();
    uc1.Foo = “Set the property”;
    Assert.AreEqual(”Set the property”, uc1.Foo);
    });
    }

    the test should fail, but it succeeds.

    basically the RunCodeAsSTA must not only kicks off the new Thread, it should be wait for the thead to complete before return.

  4. sacha said

    am November 19 2008 @ 8:46 am

    Daniel thanks for your comments, I’ll Look into this.

  5. sacha said

    am November 19 2008 @ 9:03 am

    Daniel, I have now fixed this, thanks for letting me know about that.

  6. 2008 November 19 - Links for today « My (almost) Daily Links said

    am November 19 2008 @ 9:22 am

    [...] Sacha Barber on NUnit STA Threads & Testing WPF [...]

  7. Andrew Smith said

    am November 19 2008 @ 1:37 pm

    I didn’t try out the code but in reading it I’m wondering, wouldn’t the unit test pass if the assert failed or if you threw an exception since you’re eating the exception? I remember reading about nUnit cross threading issues a while back on Provost’s site – http://www.peterprovost.org/blog/post/NUnit-and-Multithreaded-Tests-CrossThreadTestRunner.aspx. I’m not sure if the same approach still applies or is required.

  8. Dew Drop - November 19, 2008 | Alvin Ashcraft's Morning Dew said

    am November 19 2008 @ 1:40 pm

    [...] NUnit STA Threads & Testing WPF (Sacha Barber) [...]

  9. sacha said

    am November 19 2008 @ 3:01 pm

    Andrew, Having just read Provost’s site, you probably would want to store the Exception as he shows, or you could in my example log it, or re throw and catch that outside the STA codeblock call. I didn’t do that as I wanted to keep it a simple example, I figure people could throw and catch what they want.

    Oh well looks like there are lots of resources now, for people to choose from

  10. Alex said

    am November 20 2008 @ 10:45 pm

    Hi Sacha,
    what do you think about Pex?

    http://research.microsoft.com/Pex/

    Regards,

    Alex

  11. sacha said

    am November 21 2008 @ 6:50 am

    Alex

    I haven’t heard of PEX I’ll have a look though, thanks for the link

  12. Mark Nijhof said

    am November 25 2008 @ 7:41 pm

    Very interesting read!

    I wrote a post about testing xaml behaviour using unit tests.

    http://blog.fohjin.com/2008/09/how-to-test-your-xaml-behavior-using.html

    -Mark

  13. sacha said

    am November 25 2008 @ 8:57 pm

    Mark your post is cool also. Thanks for sharing

  14. Cohen said

    am November 26 2008 @ 7:41 pm

    Oops my < and > aren’t shown…
    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3 <configSections>
    4 <sectionGroup name="NUnit">
    5 <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
    6 </sectionGroup>
    7 </configSections>
    8 <NUnit>
    9 <TestRunner>
    10 <!– Valid values are STA,MTA. Others ignored. –>
    11 <add key="ApartmentState" value="STA" />
    12 </TestRunner>
    13 </NUnit>
    14 </configuration>

  15. sacha said

    am November 26 2008 @ 8:10 pm

    Cohen

    Yeah thats works for me also.

  16. inTagger said

    am December 16 2008 @ 8:54 pm

    offtopic: sacha, did you ever try ReShaper?

  17. sacha said

    am December 17 2008 @ 8:50 am

    Yeah we use Re-Sharper at work, though I have mixed feelings about it, generally I like it.

Comment RSS · TrackBack URI

Leave a comment

Name: (Required)

eMail: (Required)

Website:

Comment: