原文作者: 周银辉  来源: 博客园 原文地址: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. 学php之翻译wordpress(2)

    wp-load.php <?php /** * Bootstrap file for setting the ABSPATH constant * and loading the wp-conf ...

  2. Android Studio导入GitHub

    方法一:引用开源项目的compile添加到gradle中http://www.zhihu.com/question/27027667 方法二:下载安装包引入:http://blog.csdn.net/ ...

  3. python socket 编程之一:编写socket的基本步骤

    一.socket 编写server的步骤: 1.第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family ...

  4. bash 变量使用技巧

  5. MYSQL <=>运算符

    <=> 与 =

  6. 正式学习React(五) Reactjs 的 PropTypes 使用方法

    propTypes 使用來規範元件Props的型別與必需狀態 var Test = React.createClass({ propTypes: { // required requiredFunc: ...

  7. opencv菜鸟学习之旅cvNorm

    Norm 计算数组的绝对范数, 绝对差分范数或者相对差分范数 double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_ty ...

  8. OpenSSL win 下报错 OPENSSL_Uplink(58D46000,08): no OPENSSL_Applink

    python 中使用 M2Crypto 想读写文件时总是报: OPENSSL_Uplink(58D46000,08): no OPENSSL_Applink windows 平台下使用 openssl ...

  9. WorkFlow4.0--入门到精通系列-专题索引

    原文地址:http://www.cnblogs.com/hegezhou_hot/archive/2011/06/15/2081405.html 开篇 首先.非常感谢大家的支持和厚爱,才有了这个系列, ...

  10. poj1458 dp入门

    Common Subsequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37551   Accepted: 15 ...