zoukankan      html  css  js  c++  java
  • 为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的具体用法您可以参考其官方文档

     

  • 相关阅读:
    10 个深恶痛绝的 Java 异常。。
    为什么公司宁愿 25K 重新招人,也不给你加到 20K?原因太现实……
    推荐一款代码神器,代码量至少省一半!
    Spring Cloud Greenwich 正式发布,Hystrix 即将寿终正寝。。
    hdu 3853 LOOPS(概率 dp 期望)
    hdu 5245 Joyful(期望的计算,好题)
    hdu 4336 Card Collector(期望 dp 状态压缩)
    hdu 4405 Aeroplane chess(概率+dp)
    hdu 5036 Explosion(概率期望+bitset)
    hdu 5033 Building (单调栈 或 暴力枚举 )
  • 原文地址:https://www.cnblogs.com/candyzkn/p/3483413.html
Copyright © 2011-2022 走看看