WPF MVVM - Unit Testing a command - Private vs Public methods? WPF MVVM - Unit Testing a command - Private vs Public methods? wpf wpf

WPF MVVM - Unit Testing a command - Private vs Public methods?


I would make them private - they aren't part of your class's public interface, that's what the public ICommand properties are for.


Personally, I'd go with private methods and I'll tell you why. You're exposing an ICommand, which to me says that the consuming view should call a CanExecute prior to calling an Execute. If they don't, they're going against the API and shooting themselves in the foot and at that point it is out of your hands. Just like if someone used reflection to set an important private variable to null and broke your class design because of this... shooting themselves in the foot. So why make the members private? Because there is no need to expose members that should not be called directly.


Basically, when you unit test the members you don't do so individually, you do so in the way the API intends for the members to be executed. So, you're not really testing the members, but moreover you're testing the command, which again means they should be tested in a pair in the specific order of:

if (CanExecute){    Execute;}


I have MVVM for something simple control of increase, decrease buttons and Slider show value.

If you have test ICommand and INotifyPropertyChanged, you can make kind of UnitTest:

[TestMethod]public void TestViewModel3(){    int min = -10;    int max = 10000;    int initVal = 50;    bool initState = false;    ToglledSliderModel model = new ToglledSliderModel(initState, initVal, min, max);    ToglledSliderViewModel viewModel = new ToglledSliderViewModel();    viewModel.Model = model;    int status = 567;    viewModel.PropertyChanged += delegate    {        status = 234;    };    for (int i = 1; i < 100; i++)    {        status = 567;        ICommand ic = viewModel.IncreaseValue;        ic.Execute(this);        Thread.Sleep(2);        Assert.AreEqual(status, 234);        Assert.AreEqual(model.SliderValue, initVal + i);    }}

you can see, i test INotifyPropertyChanged behaviour and ICommand executing