tags:

views:

466

answers:

2

I am trying to build out a unit test and would like to fake out a DropEvent.

I get an error as it is attempting to raise the event. I can't create a DragEventArgs is it protection level is internal.

System.ArgumentException : Object of type 'System.Windows.RoutedEventArgs' cannot be converted to type 'System.Windows.DragEventArgs'

I have the following...

        [Test]
    public void Test()
    {
        DesignerMock view = new DesignerMock();
        _viewModel = (PanelDesignViewModel)view.DataContext;
        view.Show();

        Assert.IsNotNull(_viewModel);

        RoutedEventArgs args = new RoutedEventArgs(DesignerCanvas.DropEvent,view.DesignerCanvas) ;
        view.DesignerCanvas.RaiseEvent(args);

        view.Close();

    }
A: 

If you're adamant that you want to test your code in this way, you could use reflections to create a DragEventArgs. However, the real question, I think, is if you're going in the right direction with your unit testing. I usually avoid doing any testing directly on my Views and stick with testing the more easily testable viewmodels (if indeed you're using MVVM) because of exactly the issue you're having right now.

dustyburwell
Not adamant, just hopeful. I am trying to test the ViewModel, but it does react to events. I can refactor the event, but I still have some VisualTreeHelper stuff going on, that still requires a mock view to go with it. Thanks.
jeff
If your ViewModel is directly responding to UI events, there's something wrong with your design... you probably misunderstood a crucial principle of MVVM which says that the ViewModel is independent from the UI
Thomas Levesque
+1  A: 

As ascalonx says, you shouldn't test your View, only your ViewModel. This means your ViewModel needs to be decoupled from the View. Instead of an event handler, expose a simple public method on the ViewModel that will do the work you need, and simply call this in your test. To make your View call this method, use an attached behavior. Caliburn has a nice "Actions" attached behavior to do just this.

You mention you also have some VisualTreeHelper stuff "going on". This is a violation of the M-V-VM pattern, as it couples your VM to a specific V implementation. What ever your doing there, abstract it out to a "service" interface and use IoC or Service Locator to provide this service to your VM. I might suggest looking at Onyx for this (disclaimer: I'm the author of this library). It provides a flexible and easy to use mechanism for providing services to your VM.

wekempf