1

I'm developing an application in WPF, with MVVMLight framework.

I'm trying to make unit tests (i'm novice in that). So I try to simulate my view by subscribing to the CanExecuteChanged event on my command and verify that it is correctly called. But when I do that it is never called, even if I call the RaiseCanExecuteChanged method.

Here is a very simple sample:

bool testCanExec = false;
var testCmd = new RelayCommand(
                     execute:    () => { System.Diagnostics.Debug.WriteLine($"Execute call"); },
                     canExecute: () => { System.Diagnostics.Debug.WriteLine($"CanExecute call"); return testCanExec; }
                );
testCmd.CanExecuteChanged += ((sender, args) => { System.Diagnostics.Debug.WriteLine($"CanExecuteChanged call"); });
testCanExec = true;
testCmd.RaiseCanExecuteChanged(); // <= nothing in output
testCmd.Execute(null);            // <= output: "CanExecute call", "Execute call"

What I really can't understand is that it seems to work with my button. I don't know how but it enables and disables properly.

Thank's for your help.

Corabox
  • 157
  • 10

1 Answers1

2

The RelayCommand's RaiseCanExecuteChanged method simply calls CommandManager.InvalidateRequerySuggested() which has no effect in the context of a unit test: https://github.com/lbugnion/mvvmlight/blob/b23c4d5bf6df654ad885be26ea053fb0efa04973/V3/GalaSoft.MvvmLight/GalaSoft.MvvmLight%20(NET35)/Command/RelayCommandGeneric.cs

..because there are no controls that have subscribed to the CommandManager.RequerySuggested event.

Also, you are generally not really supposed to write unit tests that test the functionality of a third-party framework. You should probably focus on testing your own custom functionality.

But if you want to test the CanExecute method, you should simply call it instead of raising the CanExecuteChanged event:

bool b = testCmd.CanExecute(null);  
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thank you for the explanation.In fact I didn't want to test the MVVMLight Framework, I just wanted to be sure the CanExecuteChanged event correctly raises because the CanExecute method uses many other properties so I have to call RaiseCanExecuteChanged method each time one of these field is changed. – Corabox Mar 01 '18 at 16:44