Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 663
jeff Avatar asked Mar 11 '09 20:03

jeff


People also ask

How do you write unit testing for MVVM?

Setup Unit Testing Dependencies In your Android Studio Project, the following are the three important packages inside the src folder: app/src/main/java/ — Main java source code folder. app/src/test/java/ — Local unit test folder. app/src/androidTest/java/ — Instrumentation test folder.

Why is Mvvm good for testing?

MVVM is the best choice for implementing unit tests compared with MVP and MVC because you can write test cases for both the ViewModel and Model layer without the need to reference the View and mock its objects.

How and what we will test in MVVM?

MVVM – Unit Testing The idea behind unit testing is to take discrete chunks of code (units) and write test methods that use the code in an expected way, and then test to see if they get the expected results. Being code themselves, unit tests are compiled just like the rest of the project.

Do you have to use MVVM with WPF?

The Windows Presentation Framework (WPF) takes full advantage of the Model-View-ViewModel (MVVM) pattern. Though it is possible to create WPF applications without using the MVVM pattern, a little investment in learning can make building WPF applications much simpler.


2 Answers

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!

like image 137
Orion Edwards Avatar answered Sep 22 '22 05:09

Orion Edwards


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.

like image 22
Andy Avatar answered Sep 22 '22 05:09

Andy