1、對(duì)普通類(lèi)(非WPF UI組件)進(jìn)行測(cè)試:
這和在.Net2.0中使用NUnit進(jìn)行測(cè)試時(shí)一樣,不會(huì)出現(xiàn)任何問(wè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、對(duì)WPF UI組件進(jìn)行測(cè)試
使用NUnit對(duì)WPF UI組件(比如MyWindow,MyUserControl)進(jìn)行測(cè)試的時(shí)候,NUnit會(huì)報(bào)如下異常:“The calling thread must be STA, because many UI components require this”。
下面是錯(cuò)誤的測(cè)試代碼:
以下是引用片段:
[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,我們可以編寫(xiě)一個(gè)輔助類(lèi)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;
}
}
}
并編寫(xiě)正確的測(cè)試代碼:
以下是引用片段:
[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時(shí),您需要添加對(duì)nunit.framework.dll的引用,并對(duì)測(cè)試類(lèi)添加[TestFixture]屬性標(biāo)記以及對(duì)測(cè)試方法添加[Test]屬性標(biāo)記,然后將生成的程序集用nunit.exe打開(kāi)可以了,關(guān)于NUnit的具體用法您可以參考其官方文檔。