I am trying to practice strict TDD and have run into issue related to DelegateCommands and testing that CanExecute has been called.
These are my two test titles: "When I select an item from the list I should be able to add child items" "When no item开发者_JAVA技巧 is selected from the list I should not be able to add child items"
now the first test passes because CanAddChildItems is never called by my unit test, so I wrote the second test to ensure that CanAddChildItems is getting called. It is not even if I Put AddChildItems.RaiseCanExecuteChaned() into the setter of SelectedListItem.
Obviously the application does not behave as required without the AddChildItems.RaiseCanExecuteChaned() but I can't put that in if I don't have a test that really tests it!
So any ideas how I can confidently test this scenario?
Assumptions:
Your ViewModel exposes properties and commands for the view to bind to.
EnablesAddChildItemsIfAnItemHasBeenSelected()
viewModel.AddChildItemsCommand.CanExecuteChanged += MarkNotificationReceived; // dummy handler in test fixture
viewModel.SelectedItem = someItemVM;
Assert.IsTrue(viewModel.AddChildItemsCommand.CanExecute(params))
Assert.IsTrue(this.ReceivedCanExecuteChangedNotification) // flag in test fixture
If you find yourself doing this often, you can create your own utility classes PropertyChangeListener / CanExecuteChangeListener and pass in your viewmodel and property/command name.
DisablesAddChildItemsIfThereIsNoSelection
viewModel.SelectedItem = someItemVM
var addChildItemsCmd = viewModel.AddChildItemsCommand;
var changeListener = new CanExecuteChangeListener(addChildItemsCmd);
viewModel.SelectedItem = null
Assert.IsFalse(addChilditemsCmd.CanExecute(params))
Assert.IsTrue(changeListener.NotificationReceived)
精彩评论