ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 为WPF项目创建单元测试

为WPF项目创建单元测试

原创 Linux操作系统 作者:思月行云 时间:2009-07-22 11:53:21 0 删除 编辑

作者:周银辉  来源:博客园  时间:2009-02-27  阅读:490 次  原文链接   [收藏]  

小提示:点击可切换浏览

可能你已发现一个问题,我们无法使用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);
        }

     }

wpfUnitTestError1.png


为了让调用线程为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);
              }
);   

        }

  }



wpfUnitTestOK.png

另外,使用NUnit时,您需要添加对nunit.framework.dll的引用,并对测试类添加[TestFixture]属性标记以及对测试方法添加[Test]属性标记,然后将生成的程序集用nunit.exe打开就可以了,关于NUnit的具体用法您可以参考其官方文档。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21146222/viewspace-609881/,如需转载,请注明出处,否则将追究法律责任。

上一篇: WPF中的动画
请登录后发表评论 登录
全部评论

注册时间:2009-03-18

  • 博文量
    49
  • 访问量
    66850