WPF單元測(cè)試方法總結(jié)
WPF單元測(cè)試的創(chuàng)建需要有一定編程經(jīng)驗(yàn)的開發(fā)人員,才能熟練的操作。那么,在這篇文章中我們將針對(duì)WPF單元測(cè)試的創(chuàng)建過程做一個(gè)簡(jiǎn)單的介紹。 #t#
1,對(duì)普通類(非WPF UI組件)進(jìn)行測(cè)試:
這和在.Net2.0中使用NUnit進(jìn)行測(cè)試時(shí)一樣,不會(huì)出現(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,對(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ò)誤的WPF單元測(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,我們可以編寫一個(gè)輔助類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(Security
Action.Demand)]- private static void ThrowException
PreservingStack(Exception exception) {- FieldInfo remoteStackTraceString =
typeof(Exception).GetField( "_remoteStack
TraceString", BindingFlags.Instance |
BindingFlags.NonPublic);- remoteStackTraceString.SetValue(exception,
exception.StackTrace + Environment.NewLine);- throw exception;
- }
- }
- }
并編寫正確的WPF單元測(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ì)WPF單元測(cè)試類添加[TestFixture]屬性標(biāo)記以及對(duì)測(cè)試方法添加[Test]屬性標(biāo)記,然后將生成的程序集用nunit.exe打開就可以了。