/// <summary> /// Asserts that the execution of the provided action raises the property changed event. /// </summary> /// <typeparam name="T">The type of the observable.</typeparam> /// <param name="observable">The observable which should raise the property changed event.</param> /// <param name="expression">A simple expression which identifies the property (e.g. x => x.Name).</param> /// <param name="raisePropertyChanged">An action that results in a property changed event of the observable.</param> /// <param name="expectedChangedCount">The expected count of PropertyChanged events.</param> /// <param name="expectedChangedCountMode">The mode defines how the expected changed count is used as assert condition.</param> /// <exception cref="AssertException">This exception is thrown when no or more than one property changed event was /// raised by the observable or the sender object of the event was not the observable object.</exception> public static void PropertyChangedEvent <T>(T observable, Expression <Func <T, object> > expression, Action raisePropertyChanged, int expectedChangedCount, ExpectedChangedCountMode expectedChangedCountMode) where T : class, INotifyPropertyChanged { if (observable == null) { throw new ArgumentNullException(nameof(observable)); } if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (raisePropertyChanged == null) { throw new ArgumentNullException(nameof(raisePropertyChanged)); } if (expectedChangedCount < 0) { throw new ArgumentOutOfRangeException(nameof(expectedChangedCount), "A negative number is not allowed."); } string propertyName = GetProperty(expression).Name; int propertyChangedCount = 0; PropertyChangedEventHandler propertyChangedHandler = (sender, e) => { if (observable != sender) { throw new AssertException("The sender object of the event isn't the observable"); } if (e.PropertyName == propertyName) { propertyChangedCount++; } }; observable.PropertyChanged += propertyChangedHandler; raisePropertyChanged(); observable.PropertyChanged -= propertyChangedHandler; if (propertyChangedCount < expectedChangedCount && expectedChangedCountMode != ExpectedChangedCountMode.AtMost) { throw new AssertException(string.Format(null, "The PropertyChanged event for the property '{0}' was raised {1} times. Expected is {2} times{3}.", propertyName, propertyChangedCount, expectedChangedCount, expectedChangedCountMode == ExpectedChangedCountMode.AtLeast ? " or more" : "")); } else if (propertyChangedCount > expectedChangedCount && expectedChangedCountMode != ExpectedChangedCountMode.AtLeast) { throw new AssertException(string.Format(null, "The PropertyChanged event for the property '{0}' was raised {1} times. Expected is {2} times{3}.", propertyName, propertyChangedCount, expectedChangedCount, expectedChangedCountMode == ExpectedChangedCountMode.AtMost ? " or less" : "")); } }
/// <summary> /// Asserts that the execution of the provided action raises the CanExecuteChanged event of the command. /// </summary> /// <param name="command">The command.</param> /// <param name="raiseCanExecuteChanged">An action that results in a CanExecuteChanged event of the command.</param> /// <param name="expectedChangedCount">The expected count of CanExecuteChanged events.</param> /// <param name="expectedChangedCountMode">The mode defines how the expected changed count is used as assert condition.</param> /// <exception cref="AssertException">This exception is thrown when no or more than one CanExecuteChanged event was /// raised by the command or the sender object of the event was not the command object.</exception> public static void CanExecuteChangedEvent(ICommand command, Action raiseCanExecuteChanged, int expectedChangedCount, ExpectedChangedCountMode expectedChangedCountMode) { if (command == null) { throw new ArgumentNullException(nameof(command)); } if (raiseCanExecuteChanged == null) { throw new ArgumentNullException(nameof(raiseCanExecuteChanged)); } if (expectedChangedCount < 0) { throw new ArgumentOutOfRangeException(nameof(expectedChangedCount), "A negative number is not allowed."); } int canExecuteChangedCount = 0; EventHandler canExecuteChangedHandler = (sender, e) => { if (command != sender) { throw new AssertException("The sender object of the event isn't the command"); } canExecuteChangedCount++; }; command.CanExecuteChanged += canExecuteChangedHandler; raiseCanExecuteChanged(); command.CanExecuteChanged -= canExecuteChangedHandler; if (canExecuteChangedCount < expectedChangedCount && expectedChangedCountMode != ExpectedChangedCountMode.AtMost) { throw new AssertException(string.Format(null, "The CanExecuteChanged event was raised {0} times. Expected is {1} times{2}.", canExecuteChangedCount, expectedChangedCount, expectedChangedCountMode == ExpectedChangedCountMode.AtLeast ? " or more" : "")); } else if (canExecuteChangedCount > expectedChangedCount && expectedChangedCountMode != ExpectedChangedCountMode.AtLeast) { throw new AssertException(string.Format(null, "The CanExecuteChanged event was raised {0} times. Expected is {1} times{2}.", canExecuteChangedCount, expectedChangedCount, expectedChangedCountMode == ExpectedChangedCountMode.AtMost ? " or less" : "")); } }