using System; using System.ComponentModel; using System.Linq.Expressions; using NUnit.Framework; namespace Tests { /// /// Collection of usefull extension methods to help testing viewmodel properties. /// public static class TestViewModelHelper { /// /// Test that a string property of a viewmodel class has a correct behavior: /// - write a value and read it back to check its value /// - ensure that the PropertyChanged event is raised properly /// /// Type of the ViewModel /// Type of the property to test. Supported types are bool, string, int and bouel /// Instance of a ViewModel object /// Expression which evaluate the property to test public static void TestProperty(T viewmodel, Expression> expression) where T : INotifyPropertyChanged { if(expression.Body is MemberExpression) { MemberExpression memberExpression = (MemberExpression) expression.Body; if (expression.Body.Type == typeof(bool)) { TestViewModelProperty(viewmodel, memberExpression.Member.Name, true, false); } else if (expression.Body.Type == typeof(string)) { TestViewModelProperty(viewmodel, memberExpression.Member.Name, "value1", "value2"); } else if (expression.Body.Type == typeof(int)) { TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1, 99); } else if (expression.Body.Type == typeof(double)) { TestViewModelProperty(viewmodel, memberExpression.Member.Name, 1.0, 99.0); } else { throw new NotSupportedException("Type is not supported"); } } } /// /// Test that a property of a viewmodel class has a correct behavior: /// - write a value and read it back to check its value /// - ensure that the PropertyChanged event is raised properly /// /// Type of the viewmodel /// ViewModel instance /// Name of the property to test private static void TestViewModelProperty(T viewModel, string propertyName, U value1, U value2) where T : INotifyPropertyChanged { bool propertyChanged; viewModel.PropertyChanged += (s, e) => propertyChanged = e.PropertyName == propertyName; propertyChanged = false; viewModel.SetValue(propertyName, value1); Assert.IsTrue(propertyChanged); Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value1)); propertyChanged = false; viewModel.SetValue(propertyName, value2); Assert.IsTrue(propertyChanged); Assert.IsTrue(viewModel.GetValue(propertyName).Equals(value2)); } /// /// Gets a property on a object by reflection /// /// Type of the value to get /// Instance of the object which has the property /// Name of the property to get /// Value of the property on this object private static T GetValue(this object obj, string propertyName) { var propertyInfo = obj.GetType().GetProperty(propertyName); return (T)propertyInfo.GetValue(obj, null); } /// /// Sets a property on a object by reflection /// /// Type of the value to set /// Instance of the object which has the property /// Name of the property to set /// Value to set private static void SetValue(this object obj, string propertyName, T value) { var propertyInfo = obj.GetType().GetProperty(propertyName); propertyInfo.SetValue(obj, value, null); } } }