MouseEventArgs に依存する単体テスト機能?
-
13-09-2019 - |
質問
私は現在、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 は、ビューの ItemsControl がバインドする PaintObject オブジェクトのコレクションです。
- PaintObject は、使用可能なすべての PaintObjects (Rectangle、Circle、Triangle など) の基本クラスです。
- SelectedObject (PaintObject 型) は、別の Prism モジュール (ツールボックス) の選択プロセスによって決定されます。
問題は、OnMouseLeftButtonDown メソッドを単体テストするにはどうすればよいでしょうか?問題は、MouseEventArgs に大きく依存しており、MouseEventArgs をモック/スタブする良い方法がわからないことです。
解決
マウスイベントを消費し、放出する追加の層を使用します。次に、あなたのユニットテストのためにその層をモック/スタブすることができます。
他のヒント
ので、私は添付プロパティでユニットテストのこのタイプを実行するために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%を伝えることはできませんが、うまくいけば、このスニペットは、誰かに参考になります。