单元测试功能依赖于MouseEventArgs?

时间:2009-08-13 15:35:54

标签: wpf mvvm prism mouseevent

我目前正在开发一个类似MSPaint的WPF应用程序。但是,我不会使用铅笔工具或类似的东西,但使用对象(矩形,圆形,三角形等)。我使用Prism和MVVM模型来实现可测试性和可维护性。

我现在遇到了一个问题。我有一个CanvasView.xaml(顾名思义)我正在绘制的画布。我已经实现了自定义Prism CommandBehaviors(即MouseDownCommandBehavior),以提供一种将ViewModel的命令绑定到画布上的鼠标操作的方法。

基本设置如下:

public DelegateCommand<MouseEventArgs> MouseLeftButtonDownCommand { get; set; }

public CanvasViewModel(ICanvasView view, IEventAggregator eventAggregator) : base(view)
{
    m_View = view;
    m_EventAggregator = eventAggregator;
    m_EventAggregator.GetEvent<ToolboxSelectionChangedEvent>().Subscribe(OnToolboxSelectionChanged);


    MouseLeftButtonDownCommand = new DelegateCommand<MouseEventArgs>(OnMouseLeftButtonDown);
}

public void OnMouseLeftButtonDown(MouseEventArgs args)
{
    Point position = m_View.GetPosition(args);

    if(SelectedObject!=null){
        PaintObject po = SelectedObject.Clone();
        Canvas.SetLeft(po,position.X);
        Canvas.SetTop(po,position.Y);
        PaintObjects.Add(po);
    }
}

代码中没有的一些东西:

  • PaintObjects是一个PaintObject对象的集合,View上的ItemsControl绑定到
  • PaintObject是所有可用的PaintObjects(矩形,圆形,三角形等)的基类。
  • SelectedObject(类型为PaintObject)由另一个Prism模块(工具箱)中的选择过程确定

问题是如何对OnMouseLeftButtonDown方法进行单元测试?问题是它严重依赖于MouseEventArgs,我真的不知道模拟/存根MouseEventArgs的好方法。

2 个答案:

答案 0 :(得分:6)

我已经能够使用WPF事件路由系统来执行这种带附加属性的单元测试,并且我认为它将与UIElement的任何其他后代(Windows等)一样工作,因为此代码段中的.RaiseEvent()方法由UIElement类提供:

 [TestMethod]
  public void ThingsShouldHappenWhenMouseIsClicked()
  {
     // ARRANGE
     var itemsControl = new ItemsControl ();
     var myDependencyMock = new Mock<IMyDependency>();
     // provide dependency to a dependency property
     MyAttachedProperty.SetDragDropHandler(itemsControl, myDependencyMock.Object);

     var leftClickEventArgs = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
     {
        RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
        Source = _itemsControl
     };

     // ACT
     itemsControl.RaiseEvent(leftClickEventArgs);

     // ASSERT
     myDependencyMock.Verify(x => x.TheThingHappened());
  }

我无法100%确定这是否适用于您在问题中列出的特定控件类型,但希望此代码段对某人有用。

答案 1 :(得分:3)

使用其他图层来使用和发出鼠标事件。然后你可以为该单元测试存根/模拟该层。