I have some code that raises PropertyChanged events and I would like to be able to unit test that the events are being raised correctly.
The code that i
Don't write a test for each member - this is much work
(maybe this solution is not perfect for every situation - but it shows a possible way. You might need to adapt it for your use case)
It's possible to use reflection in a library to test if your members are all responding to your property changed event correctly:
The following code can be used as a library and shows how to test the following generic class
using System.ComponentModel;
using System.Linq;
///
/// Check if every property respons to INotifyPropertyChanged with the correct property name
///
public static class NotificationTester
{
public static object GetPropertyValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
public static bool Verify(T inputClass) where T : INotifyPropertyChanged
{
var properties = inputClass.GetType().GetProperties().Where(x => x.CanWrite);
var index = 0;
var matchedName = 0;
inputClass.PropertyChanged += (o, e) =>
{
if (properties.ElementAt(index).Name == e.PropertyName)
{
matchedName++;
}
index++;
};
foreach (var item in properties)
{
// use setter of property
item.SetValue(inputClass, GetPropertyValue(inputClass, item.Name));
}
return matchedName == properties.Count();
}
}
The tests of your class can now be written as. (maybe you want to split the test into "event is there" and "event raised with correct name" - you can do this yourself)
[TestMethod]
public void EveryWriteablePropertyImplementsINotifyPropertyChangedCorrect()
{
var viewModel = new TestMyClassWithINotifyPropertyChangedInterface();
Assert.AreEqual(true, NotificationTester.Verify(viewModel));
}
Class
using System.ComponentModel;
public class TestMyClassWithINotifyPropertyChangedInterface : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
private int id;
public int Id
{
get { return id; }
set { id = value;
NotifyPropertyChanged("Id");
}
}
}