Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight单元测试中依赖对象的处理_Silverlight_Unit Testing - Fatal编程技术网

Silverlight单元测试中依赖对象的处理

Silverlight单元测试中依赖对象的处理,silverlight,unit-testing,Silverlight,Unit Testing,我用Silverlight代码使用NUnit和Moq编写单元测试已经有一段时间了。我一直遇到的一个问题与DependencyObjects有关 如果有任何东西是从DependencyObject派生的,那么我不能在测试中实例化它。例如,MouseEventArgs派生自DependencyObject。如果我有接受这些参数的代码,我无法创建这些参数,原因有几个。。。其中之一是它是一个DependencyObject 据我所知,DependencyObject的基本构造函数正在尝试使用一些不存在的

我用Silverlight代码使用NUnit和Moq编写单元测试已经有一段时间了。我一直遇到的一个问题与DependencyObjects有关

如果有任何东西是从DependencyObject派生的,那么我不能在测试中实例化它。例如,MouseEventArgs派生自DependencyObject。如果我有接受这些参数的代码,我无法创建这些参数,原因有几个。。。其中之一是它是一个DependencyObject


据我所知,DependencyObject的基本构造函数正在尝试使用一些不存在的静态,除非整个Silverlight系统启动并运行。从DependencyObject派生的类的任何构造都会引发异常。糟糕透了

我不使用,因为它实际上不是单元测试,需要UI。我需要运行真正的无头单元测试

无论如何,我想到的最好办法是包装这些对象,并为它们提供接口,如
ITimelineMarker
,我为它们提供扩展方法:
timelineMarker.ToInterface()
。这很有效,我可以嘲笑他们。。。但我想知道:


有人想出了更好的方法来处理Silverlight单元测试中的依赖对象吗?

您看过TestDriven.NETs Silverlight NUnit项目吗?
我可以在抽象类中看到DependencyObject

厚颜无耻地从Rhino Mock中剽窃,想象你有一个抽象类:

public abstract class MessageBase {
   private List<User> _receivers = new List<User>();
   public void Send() {
      //Some setup
      DetermineReceivers();
      SendMessages();
   }
   private void SendMessages() {
      //Lots of logic
   }
   protected abstract void DetermineReceivers();
   protected void AddReceiver(Group g) {
      //Lots of logic <---- Test this
   }
}
公共抽象类MessageBase{
私有列表_receivers=新列表();
公共无效发送(){
//一些设置
确定接收器();
SendMessages();
}
私有void发送消息(){
//很多逻辑
}
受保护的抽象无效确定接收者();
受保护的空添加接收器(g组){

//大量逻辑尝试使用。由于它伪造了Silverlight基础结构,因此可能有助于解决问题异常。

为什么应用程序逻辑直接绑定到Silverlight事件和对象?尝试通过其UI测试应用程序逻辑的警告是众所周知的反模式,并已被模式所取代以更有效的方式解决这个问题

您的UI实际上应该只关注UI事件,并将任何处理传递到另一个层,然后在UI中剩下的唯一要测试的是图形响应(例如,当您单击按钮时,面板会从侧面滑入),而测试此类交互的唯一好方法是实际执行单击


也许对您的问题更合适的答案是,您需要重构代码,以使用MVC、MVP或MVVM等模式,这样您就可以独立于UI层测试应用程序逻辑。

是的。这就是我们所使用的。问题发生在该设置中。不幸的是,这不起作用。我需要替换的对象派生自DependencyObject(例如MouseEventArgs),该对象通常是密封的,构造函数是内部的:(抱歉,但我在msdn中没有看到任何从DependencyObject派生的Mouseeventarg。您能提供一个链接吗?@drozzy:Doat!您是对的……Mouseeventarg不是从DependencyObject派生的。不过,它确实遇到了非常类似的问题……它是一个带有内部构造函数的密封类。下面是一些更好的示例。)(在我脑海中)是System.Windows.Media.SolidColorBrush或System.Windows.Media.TimelineMarker。另外,Rhino mock在Silverlight中工作吗?这只是一个小问题……Moq在SL中工作,可以模拟抽象类。即使我尝试使用我可以派生的类型(System.Windows.Media.Brush),我仍然在基构造函数中遇到异常。如果我误解了(或对silverlight不太了解),请原谅,但这两个类都有如下形式的构造函数:public TimelineMarker()public SolidColorBrush()在构造期间,它们似乎都不需要任何依赖项对象。能否提供要测试的特定案例或场景?它们派生自DependencyObject。DependencyObject的基本构造函数在构造时抛出异常。场景很简单:在测试中构造SolidColorBrush。它抛出。“从DependencyObject派生的类的任何构造都会引发异常"--什么是异常类和错误消息?不幸的是,它使用的是TypeMock隔离器,这不是我喜欢的。我已经考虑过了,但我更喜欢一种更好的方法,使我的类更少地依赖于系统对象。+1这是一个很好的问题…事实证明,在大多数情况下,这对我来说不是问题…我使用只要我能,就可以使用MVVM模式,这很好。但是创建这种分离会导致代码中仍然存在一些逻辑。例如……假设我在视频中有一堆时间线标记。我想在我的应用程序逻辑中处理这些标记。我可以在代码中提取它们,并将它们传递到我的逻辑和流程中它们。它们实际上只是数据。这样做的问题是时间轴标记源于DependencyObject。继续:在我发现我想要处理DependencyObject的每一种情况下,(它几乎总是简单的旧数据样式类)我的方法是将对象封装在一个实现类似接口的代理中。它允许我的MVVM模式继续正常工作。我的目标是尽可能多地利用代码隐藏…如果它在代码隐藏中,则无法对其进行测试。一些从DependencyObject派生的数据对象挫败了我的计划:)如果有一种方法来构造这些对象,它将简化我的代码。不过,回答得好。我在应用程序中有一些类似的范例,我所做的就是创建一个可以称为子视图的东西。假设你有一个TimelineViewModel,它有一组TimelineMarkerViewModels,我将创建一个用户控件和一个使用该c的数据模板控制
TestFixture
public sealed class MessageBaseTester {
 public abstract class MockMessageMocker
 {
    public abstract List<Group> RecipientsGroups { get; set; }
 }
 private class MockMessage : MessageBase {
   private MockMessageMocker _mock;
   public MockMessage(MockMessageMocker mock) {
      _mock = mock;
   }
   protected override void DetermineReceivers() {
      if (_mock.RecipientsGroups != null)
         foreach(Group g in _mock.RecipientsGroups)
            base.AddReceiver(g);
   }
 }
}
 Test
 public void ShouldblablablaWhenBlabla() {
    var SuThelper = mocks.Stub();
    var SuT = new MockMessage(SuThelper);
    using (mocks.Record())
    {
       Expect.Call(SuTHelper.RecipientsGroups).Return(
             new List<Group>{ new Group(...) });
    }
    using (mocks.Playback())
    {
       SuT.Send();
    }
 }