• 为WPF项目创建单元测试


    原文作者: 周银辉  来源: 博客园 原文地址:http://www.cnblogs.com/zhouyinhui/archive/2007/09/30/911522.html

    可能你已发现一个问题,我们无法使用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的具体用法您可以参考其官方文档

     

  • 相关阅读:
    Android安全——加固原理
    Android安全–Dex文件格式详解
    我的第二个开源库SuperTextView——中文文档
    【解决方案】: hyper-v 导入虚拟机报这个错误 32784
    【经验】谈谈怎么找自己想要的资源吧~
    有吧友需要PDF的下载站点,好吧,我这边汇总一下
    lucene、lucene.NET详细使用与优化详解
    轻量级开源内存数据库SQLite性能测试
    SQLite介绍、学习笔记、性能测试
    十个 MongoDB 使用要点
  • 原文地址:https://www.cnblogs.com/candyzkn/p/3483413.html
Copyright © 2020-2023  润新知