jeff
jeff

Reputation: 3327

WPF MVVM and Unit Testing

I have been working on a WPF application and I am using the ModelViewViewModel design pattern. I have a number of events that come out of the view, that result in ViewModel activity.

What is the resonable way to get these events raised from a UnitTest? For example, I want to simulate the drop event. I don't really want to build a stub view, just to raise the event.

Any suggestions welcome.

Thanks.

Upvotes: 9

Views: 8539

Answers (4)

Adriano Machado
Adriano Machado

Reputation: 232

Why don't you use a mocking framework, such as Moq? Check out their quick start, it has a sample on mocking events. The url is: http://code.google.com/p/moq/wiki/QuickStart

Upvotes: 0

wekempf
wekempf

Reputation: 2788

Don't raise an event, just call the handlers (which means they should be public, and probably take less event handler centric arguments). Check out how this is done in Caliburn (http://www.codeplex.com/caliburn) using "Actions".

Upvotes: 0

Orion Edwards
Orion Edwards

Reputation: 123662

According to the MVVM pattern:

  • The View knows about the ViewModel - it will have a reference to it either as a concrete instance or an interface
  • The ViewModel should not know about the view at all.

If you need to handle events, then there are two ways which I know of to do it:

1:   Expose a command in your viewmodel, and use databinding to trigger it. This is my preferred way, eg:

class MyViewModel
{
    public ICommand ClickCommand { get; set; }
}

<Button Command="{Binding Path=ClickCommand}" />

If you do this then you can test the command by simply calling myViewModel.ClickCommand.Execute manually.

2:   Expose a function in the viewmodel, and write the absolute minimum in the .xaml.cs file to handle the event and call the function, eg:

class MyViewModel
{
    public void HandleClick(){ }
}

<Button Click="MyClickHandler">

//.xaml.cs file
public void MyClickHandler( Object sender, EventArgs e ) {
    m_viewModel.HandleClick()
}

If you do this, then you can test by simply calling myViewModel.HandleClick manually. You shouldn't need to bother with unit testing the MyClickHandler code as it's only 1 line!

Upvotes: 18

Andy
Andy

Reputation: 30418

It sounds like you have an event handler for the drop event directly in your ViewModel class. Would it make more sense to have the handler in your UI layer, which in turn will call a function in your ViewModel? This way, your unit test could just call the function (simulating a drag and drop operation, as far as the ViewModel is concerned).

Plus, it would better separate your ViewModel from your UI code.

Upvotes: 1

Related Questions