原文作者: 周银辉  来源: 博客园 原文地址: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);
        }
     }

为了让调用线程为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的具体用法您可以参考其官方文档

为WPF项目创建单元测试的更多相关文章

  1. 项目中创建单元测试—VS2012

    我们在每个项目的开发过程中,开发完一个功能,自己首先需要测试一下,VS提供了很方便的测试功能,可以很容易的创建单元测试,但是在VS2012中类名上点击右键没有『创建单元测试』这个菜单,需要先进行设置一 ...

  2. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

  3. 使用 DotNet CLI 创建自定义的 WPF 项目模板

    描述 当我们安装完 DotNetCore 3.0 版本的 SDK 后,我们就可以创建基于 DotNetCore 的 WPF 项目模板,通过如下 CLI 可以方便快捷的创建并运行我们的项目: dotne ...

  4. springmvc 项目完整示例02 项目创建-eclipse创建动态web项目 配置文件 junit单元测试

    包结构 所需要的jar包直接拷贝到lib目录下 然后选定 build path 之后开始写项目代码 配置文件 ApplicationContext.xml <?xml version=" ...

  5. IDEA中SpringBoot项目快速创建单元测试

    如何在IDEA中对于SpringBoot项目快速创建单元测试 创建测试用例 右键需要进行测试的方法,选择GO TO然后选择Test 点击Create New Test 勾选需要创建单元测试的方法 然后 ...

  6. 如何创建一个基于 .NET Core 3 的 WPF 项目

    在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF:同时还发布了 Visual Studio 2019 预览版 ...

  7. VS2012安装完成之后,用自带的Blend无法创建WPF项目,打开WPF项目无法设计

    Visual Studio 2012安装完成之后, 打开自带的Blend for Visual Studio 无法创建新的WPF或者Silverlight项.打开WPF项目无法编辑的原因: 1.VS自 ...

  8. 用Visual C++创建WPF项目的三种主要方法

    用Visual C++创建WPF项目的三种主要方法 The problem with using XAML from C++ Because C++ doesn't support partial c ...

  9. VS Code Java 2 月更新!教育特别版:单元测试、GUI开发支持、Gradle项目创建、以及更多!

    新春快乐!欢迎来到 Visual Studio Code Java 的 2 月更新,这个月我们给大家带来了一期教育特别版.每年的年初是许多学校开学的时间,为了给学生和教师提供在 Visual Stud ...

随机推荐

  1. 纯CSS3技术 加载中

    你能相信吗?这些都是由一个DIV元素实现的动画,纯CSS3技术 html  <div class="loader">加载中...</div> css: 图( ...

  2. xml文件的解析

    1. xml文件的解析 void CDataMgr::readStringData() { std::string xml_name = "config/string.xml"; ...

  3. PHPExcel导出

    第一,先查出数据库里面要生成Excel的数据,如: $data= M('User')->findAll();   //查出数据 $name='Excelfile';    //生成的Excel文 ...

  4. ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 错误分析

    目录(?)[+] 1. 问题起因 最近在进行Oracle的一些操作时,总会遇到这个错误:  ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小,错误如下: ORA-00604: ...

  5. ASCII、ANSI、GB2312、Unicode、UTF-8之间的关系

    1.ASCII码: ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统.它主要用于 ...

  6. android layout的布局

    1.android:layout_width.android:layout_heigth 表示控件的大小,长宽 2.andoid:layout_gravity .android:gravity表示控件 ...

  7. AdminCMD

    program AdminCMD; {$APPTYPE CONSOLE} uses Windows, ShellApi, SysUtils; function RunAsAdmin(const iEx ...

  8. psacct监视用户执行的命令,如cpu时间和内存战胜,实时进程记账

    psacct监视用户执行的命令,如cpu时间和内存战胜,实时进程记账

  9. IP defragment

    snort IP defragment 模型: BSD favors an original fragment with an offset that is less than or equal to ...

  10. linux下自动同步internet时间

    linux下很简单直接一句即可: ntpdate time.nist.gov ntp后面参数为internet时间服务器url或ip即可. 但是ntpdate命令需要root特权,如果做成自动运行每次 ...