1、對普通類(非WPF UI組件)進(jìn)行測試:
這和在.Net2.0中使用NUnit進(jìn)行測試時一樣,不會出現(xiàn)任何問題,參考下面的代碼:
以下是引用片段:
[TestFixture]
public class ClassTest
{
[Test]
public void TestRun()
{
ClassLibrary1.Class1 obj = new ClassLibrary1.Class1();
double expected = 9;
double result = obj.GetSomeValue(3);
Assert.AreEqual(expected, result);
}
}
2、對WPF UI組件進(jìn)行測試
使用NUnit對WPF UI組件(比如MyWindow,MyUserControl)進(jìn)行測試的時候,NUnit會報(bào)如下異常:“The calling thread must be STA, because many UI components require this”。
下面是錯誤的測試代碼:
以下是引用片段:
[TestFixture]
public class ClassTest
{
[Test]
public void TestRun()
{
WindowsApplication1.Window1 obj = new WindowsApplication1.Window1();
double expected = 9;
double result = obj.GetSomeValue(3);
Assert.AreEqual(expected, result);
}
}
為了讓調(diào)用線程為STA,我們可以編寫一個輔助類CrossThreadTestRunner:
以下是引用片段:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Security.Permissions;
using System.Reflection;
namespace TestUnit
{
public class CrossThreadTestRunner
{
private Exception lastException;
public void RunInMTA(ThreadStart userDelegate)
{
Run(userDelegate, ApartmentState.MTA);
}
public void RunInSTA(ThreadStart userDelegate)
{
Run(userDelegate, ApartmentState.STA);
}
private void Run(ThreadStart userDelegate, ApartmentState apartmentState)
{
lastException = null;
Thread thread = new Thread(
delegate()
{
try
{
userDelegate.Invoke();
}
catch (Exception e)
{
lastException = e;
}
});
thread.SetApartmentState(apartmentState);
thread.Start();
thread.Join();
if (ExceptionWasThrown())
ThrowExceptionPreservingStack(lastException);
}
private bool ExceptionWasThrown()
{
return lastException != null;
}
[ReflectionPermission(SecurityAction.Demand)]
private static void ThrowExceptionPreservingStack(Exception exception)
{
FieldInfo remoteStackTraceString = typeof(Exception).GetField(
"_remoteStackTraceString",
BindingFlags.Instance | BindingFlags.NonPublic);
remoteStackTraceString.SetValue(exception, exception.StackTrace + Environment.NewLine);
throw exception;
}
}
}
并編寫正確的測試代碼:
以下是引用片段:
[TestFixture]
public class ClassTest
{
[Test]
public void TestRun()
{
CrossThreadTestRunner runner = new CrossThreadTestRunner();
runner.RunInSTA(
delegate
{
Console.WriteLine(Thread.CurrentThread.GetApartmentState());
WindowsApplication1.Window1 obj = new WindowsApplication1.Window1();
double expected = 9;
double result = obj.GetSomeValue(3);
Assert.AreEqual(expected, result);
});
}
}
另外,使用NUnit時,您需要添加對nunit.framework.dll的引用,并對測試類添加[TestFixture]屬性標(biāo)記以及對測試方法添加[Test]屬性標(biāo)記,然后將生成的程序集用nunit.exe打開可以了,關(guān)于NUnit的具體用法您可以參考其官方文檔。