Testing the PropertyChanged event

Tags: TDD, WPF

Testing a ViewModel and it's properties may look quite easy at first. But ViewModels are quite treacherous to their nature. There's no guarantee that the value of a property in a unit test is the same as what the view is displaying, because of NotifyPropertyChanged (if no PropertyChanged is fired, nothing is updated in the view, right?).

And really, what use do you have of a unit test that you can't fully rely on?

I thought about solving this issue a few days back and came up with a small extension helper method that increases the test accuracy without increasing the complexity too much.

Given this Context:

    [TestFixture]

    publicclassWhen_updating_a_property_which_a_WpfControl_is_binding_to

    {

        privateViewModel _viewModel;

 

        [SetUp]

        publicvoid Context()

        {

            _viewModel = newViewModel();

            _viewModel.PropertyWithWPFBinding = 100;

        }

 

        [Test]

        publicvoid It_should_display_the_correct_value_since_it_has_fired_a_propertyChanged_event()

        {

            Assert.That(_viewModel.PropertyWithWPFBinding, Is.EqualTo(100));

        }

    }


The test will certainly pass both with or without PropertyChanged (which is bad).
So with a small modification, and with the use of Should BeDisplayedAs():

    [TestFixture]

    public class When_updating_a_property_which_a_WpfControl_is_binding_to

    {

        privateViewModel _viewModel;

 

        [SetUp]

        publicvoid Context()

        {

            _viewModel = newViewModel();

            _viewModel.MakePropertyChangedAware();

            _viewModel.PropertyWithWPFBinding = 100;

        }

 

        [Test]

        publicvoid It_should_display_the_correct_value_since_it_has_fired_a_propertyChanged_event()

        {

            _viewModel.ShouldBeDisplayedAs(x => x.PropertyWithWPFBinding, 100);

        }

    }

The test will fail if no PropertyChanged was fired. To avoid confusion I also added a more descriptive fail reason:

error message 1

Pretty sweet.

What the code really does is simply creating a listener for all ProperyChanged events that has been fired with the MakePropertyChangedAware() method. And records the values of the ViewModel only if a PropertyChanged is fired.

If you want a sample project and the source, download here.

/love Carl

Add a Comment