Introduction to unit testing in MVVM

If you are wondering why you should even write unit tests, you should also wonder why you aren’t still living in a cave and writing stuff on the walls (don't feel offended, continue reading...). Writing unit tests makes sure that you don’t break existing functionality in an application when making changes. This lowers the cost of QA (since you don’t need a technical tester executing regression tests all the time). I don’t say that a tester isn’t needed; my opinion is that at least someone else besides the developer should take a human look at the software before it is even released. If you are still not convinced why you should write unit tests, please go back to your cave and stop reading this article for the sake of your own pleasure.

This documentation does not cover the basics of unit testing. It assumes that you already know what unit tests are, and how to write them. This documentation is specifically written to explain how view models of the MVVM pattern can be unit tested, especially with the use of Catel.

Testing commands

Thanks to commands (which implement the ICommand interface), testing view models and UI logic has never been so easy. Now commands can be invoked programmatically without having to automate the UI; it is very simple to reproduce a button click during a unit test.

When testing commands, it is very important to test the state as well. The command implementation of Catel has a CanExecute and an Execute method which can be invoked manually. Therefore, it is very easy to test a command. The code below shows a test that checks whether the Remove command can be executed. At first, the command cannot be executed because there is no selected person. After the selected person is set, the command should be able to execute:

Assert.IsFalse(mainWindowViewModel.Remove.CanExecute(null));
mainWindowViewModel.SelectedPerson = mainWindowViewModel.PersonCollection[0];
Assert.IsTrue(mainWindowViewModel.Remove.CanExecute(null));

To execute a command in code, one should use the following code:

mainWindowViewModel.Remove.Execute(null);

Testing services

For more information about unit testing services, see the unit testing services documentation.