科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件经典解析:为 WPF 项目创建单元测试

经典解析:为 WPF 项目创建单元测试

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

可能你已发现一个问题,我们无法使用VS对WPF项目创建单元测试(VS2005不行,VS2008我没试过,但据说也不行),这让人很郁闷……

作者:周银辉 来源:博客园 2007年11月19日

关键字: WPF 项目 单元测试

  • 评论
  • 分享微博
  • 分享邮件
可能你已发现一个问题,我们无法使用VSWPF项目创建单元测试(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

  为了让调用线程为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;
   }
   }
  }

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章