In MVVM with WPF how do I unit test the link between the ViewModel and the View

Viewed 4992

In MVVM it is normal to connect View to the ViewModel with data binding.

Therefore if the name of a properties changes on one of the Model objects that is databound to there is no compiler error.

When the compiler will not stop a bug, the next thing I think of is “UnitTest”, However

How do you unit test this without spending forever writing a GUI test?

Is there a system that will check that all the properties that are bound to is valid, (without having to run the UI) that I can call in a unit test?

I am looking for something that will take the view, and then loop over all WPF controls, for each WPF control it will look at all the binding and check if they are valid.


By the way there have been a few good questions about how to make OnPropertyChanged safe, and/or how to test it (But done of these get down to the level of a WPF view.)


I have put a bounty on this question, as someone must have thought hard about the problem and come up with soltions.

5 Answers

Really good question. Voted it up. I would like to know the answer too.

One of the best practices I know (suggested by Josh Smith, thanks Gishu for pointing to this) is having base view model class to check in the OnPropertyChanged() method whether property really exists. E.g.:

abstract class ViewModelBase
{
    [Conditional("DEBUG")]
    public void VerifyPropertyName(string propertyName)
    {
        // Verify that the property name matches a real,  
        // public, instance property on this object.
        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        {
            if (this.ThrowOnInvalidPropertyName)
                throw new ArgumentException(propertyName);

            string msg = "Invalid property name: " + propertyName;
            Debug.Fail(msg);
        }
    }

    protected void OnPropertyChanged(string propertyName)
    {
        VerifyPropertyName(propertyName);

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}

But this wouldn't help you to find spelling problems in XAML. Hmm... I don't know any existing solution for this. Maybe guys from WPF Disciples could suggest something. I think I would go with PresentationTraceSources.DataBindingSource and add to his Listners collection instance of TextWriterTraceListener and then monitor output. As soon as we get an error or warning on our radar we should fail a test.

Found good example: WPF Snippet - Detecting Binding Errors

Hope this helps. At least a bit :).

Cheers, Anvaka.

As Anvaka points out, using a base class for your view model that checks property names can help avoid this particular problem (though it won't tell you when your VM class does its own property-change notification and ignores the method in the base class, not that I've ever seen anything like that happen in my code).

And you can (and should) instrument your code so that things that aren't working fail in a way that's visible to you. The thing that's kind of paradoxical about this is that if you know what things may fail and you watch them, they won't, because the fact that you're watching them will keep you from making the mistakes that lead them to fail (like writing a template selector that doesn't always return a template).

But fundamentally, the view is the UI, so I would be pretty surprised to find methods of testing it that weren't also methods for testing the UI.

Related