程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 為WPF項目創建單元測試

為WPF項目創建單元測試

編輯:關於.NET

可能你已發現一個問題,我們無法使用VS對WPF項目創建單元測試(VS2005不行,VS2008我沒試過,但據說 也不行),這讓人很郁悶,這裡將介紹如何使用NUnit來對WPF項目創建單元測試並解決其中的難題(但利用 NUnit來對WPF創建單元測試時並不會像針對.Net2.0一樣容易,可能會出現一些小問題).

1、對普通類(非WPF UI組件)進行測試:

這和在.Net2.0中使用NUnit進行測試時一樣,不會出現任何問題,參考下面的代碼:

以下是引用片段:

[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組件進行測試

使用NUnit對WPF UI組件(比如MyWindow,MyUserControl)進行測試的時候,NUnit會報如下異常: “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);
}
}

為了讓調用線程為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]屬性 標記以及對測試方法添加[Test]屬性標記,然後將生成的程序集用nunit.exe打開就可以了,關於NUnit的 具體用法您可以參考其官方文檔。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved