艾伟:为WPF项目创建单元测试

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

时间: 2024-10-14 04:06:14

艾伟:为WPF项目创建单元测试的相关文章

为WPF项目创建单元测试

可能你已发现一个问题,我们无法使用VS对WPF项目创建单元测试(VS2005不行,VS2008我没试过,但据说 也不行),这让人很郁闷,这里将介绍如何使用NUnit来对WPF项目创建单元测试并解决其中的难题(但利用 NUnit来对WPF创建单元测试时并不会像针对.Net2.0一样容易,可能会出现一些小问题). 1.对普通类(非WPF UI组件)进行测试: 这和在.Net2.0中使用NUnit进行测试时一样,不会出现任何问题,参考下面的代码: 以下是引用片段: [TestFixture] publ

《精通移动App测试实战:技术、工具和案例》一2.3 应用JUnit对Android项目进行单元测试

2.3 应用JUnit对Android项目进行单元测试 2.3.1 JUnit基于Android项目TestCase的应用 如果我们对基于Android系统项目开发有一定了解的话,相信一定能看出来,其核心代码是计算两个整数相加的函数.我们做单元测试当然也挑选其最核心的函数来进行测试.可以按照如下的步骤来创建一个基于Android项目的测试用例(TestCase). 第一步:选中"CalculatorOfTwoNum"项目下的"src"目录中的"com.yu

VS中模仿WPF模板创建最简单的WPF程序_C#教程

如果不用VS的WPF项目模板,如何手工创建一个WPF程序呢?我们来模仿WPF模板,创建一个最简单的WPF程序. 第一步:文件--新建--项目--空项目,创建一个空项目. 第二步:添加引用,PresentationFramework,PresentationCore,WindowsBase,System,System.Xaml,这几个是WPF的核心dll. 第三步:在项目上右键添加新建项,添加两个"xml文件",分别命名为App.xaml和MainWindow.xaml.可以看出,xam

使用WPF来创建 Metro UI程序

本文转载:http://www.cnblogs.com/TianFang/p/3184211.html 这个是我以前网上看到的一篇文章,原文地址是:Building a Metro UI with WPF,这篇文章一步步的介绍了如何实现一个Metro样式的窗口,并且效果非常好.今天看到OSChina上有这篇文章的译文:使用WPF来创建 Metro UI,翻译得非常好,这里推荐一下.  值得一提的是,除了这种一步步来的方式外,现在Codeplex中也有不少比较好的metro风格的wpf框架,可以帮

[Visual Studio] 开启Visual Studio 2012通过右键菜单创建单元测试(Unit Test)

Visual Studio 2012可以说是迄今为止微软VS开发工具中用户体验最好的产品,无论是速度还是体验以及功能,都非常出色,但是,使用了一段时间后发现有一个之前版本VS都有的功能却在Visual Studio 2012中消失了. 装了Visual Studio 2012的朋友可以自己试一试,在一个方法的名上右键点击发现操作菜单中没有创建单元测试的选项,如下图: 不知道微软是怎么想的,这个实用的功能给去掉了,但是也不用着急,成熟的软件产品一般都不会将已有的功能去掉,最多也是隐藏,下面我们就来

maven分模块web项目的单元测试

问题描述 maven分模块web项目的单元测试 50C 最近几天搞了个maven分模块的web项目的小demo.springMVC+spring+mybatis.总配置文件写在web模块中.web模块依赖service模块,service模块依赖dao模块,dao模块中有实体类和maping配置文件和dao接口.现在想分层进行单元测试.求大神指导 .在线等. 解决方案 MAVEN WEB项目 单元测试 解决方案二: 已经分模块了,各个模块用各个模块的单元测试 . 解决方案三: 用 junit @

visual studio-InstallShield Limited Edition注册失败,显示项目创建失败

问题描述 InstallShield Limited Edition注册失败,显示项目创建失败 官网下载,邮箱注册,获得序列号,新建项目,让输入离线response text,点击obtain a new request code,输入序列号,生成response text,然后项目创建失败... 为何没有让在线输入序列号?

Maven项目创建mybatis generator步骤

Maven项目创建mybatis generator需要注意事项: 1.参考资料中说的 <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator</artifactId> <version>1.3.2</version> </dependency> 这个没必要使用,使用了会一直下载不到jar 报错 2.

maven插件使用问题及项目创建

问题描述 maven插件使用问题及项目创建 解决方案 应该是xml格式不对 解决方案二: maven插件问题