Created
August 7, 2012 07:30
-
-
Save JakeGinnivan/3282830 to your computer and use it in GitHub Desktop.
Testing async commands
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Your code you are testing: | |
public IAsyncCommand SignInCommand { get; private set; } | |
public ctor() | |
{ | |
SignInCommand = new AwaitableDelegateCommand(Login); | |
} | |
private async Task Login() | |
{ | |
//stuff | |
} | |
// Your test | |
public async Task Test() | |
{ | |
var vmUnderTest = new MyViewModel(); | |
await vmUnderTest.SignInCommand.ExecuteAsync() | |
Assert.Whatever(); | |
} | |
public interface IAsyncCommand : IAsyncCommand<object>{} | |
public interface IAsyncCommand<in T> : ICommand, IRaiseCanExecuteChanged | |
{ | |
Task ExecuteAsync(T obj); | |
} | |
public class AwaitableDelegateCommand : AwaitableDelegateCommand<object>, IAsyncCommand | |
{ | |
public AwaitableDelegateCommand(Func<object, Task> executeMethod) | |
: base(executeMethod) | |
{ | |
} | |
public AwaitableDelegateCommand(Func<object, Task> executeMethod, Func<object, bool> canExecuteMethod) | |
: base(executeMethod, canExecuteMethod) | |
{ | |
} | |
} | |
public class AwaitableDelegateCommand<T> : IAsyncCommand<T> | |
{ | |
private readonly Func<T, Task> _executeMethod; | |
private readonly DelegateCommand<T> _underlyingCommand; | |
private bool _isExecuting; | |
public AwaitableDelegateCommand(Func<T, Task> executeMethod) | |
: this(executeMethod, _ => true) | |
{ | |
} | |
public AwaitableDelegateCommand(Func<T, Task> executeMethod, Func<T, bool> canExecuteMethod) | |
{ | |
_executeMethod = executeMethod; | |
_underlyingCommand = new DelegateCommand<T>(x => { }, canExecuteMethod); | |
} | |
public async Task ExecuteAsync(T obj) | |
{ | |
try | |
{ | |
_isExecuting = true; | |
RaiseCanExecuteChanged(); | |
await _executeMethod(obj); | |
} | |
finally | |
{ | |
_isExecuting = false; | |
RaiseCanExecuteChanged(); | |
} | |
} | |
public bool CanExecute(object parameter) | |
{ | |
return !_isExecuting && _underlyingCommand.CanExecute((T)parameter); | |
} | |
public event EventHandler CanExecuteChanged | |
{ | |
add { _underlyingCommand.CanExecuteChanged += value; } | |
remove { _underlyingCommand.CanExecuteChanged -= value; } | |
} | |
public async void Execute(object parameter) | |
{ | |
await ExecuteAsync((T)parameter); | |
} | |
public void RaiseCanExecuteChanged() | |
{ | |
_underlyingCommand.RaiseCanExecuteChanged(); | |
} | |
} | |
public interface IRaiseCanExecuteChanged | |
{ | |
void RaiseCanExecuteChanged(); | |
} | |
/// <summary> | |
/// A command that calls the specified delegate when the command is executed. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class DelegateCommand<T> : ICommand, IRaiseCanExecuteChanged | |
{ | |
private readonly Func<T, bool> _canExecuteMethod; | |
private readonly Action<T> _executeMethod; | |
private bool _isExecuting; | |
public DelegateCommand(Action<T> executeMethod) | |
: this(executeMethod, null) | |
{ | |
} | |
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod) | |
{ | |
if ((executeMethod == null) && (canExecuteMethod == null)) | |
{ | |
throw new ArgumentNullException("executeMethod", @"Execute Method cannot be null"); | |
} | |
_executeMethod = executeMethod; | |
_canExecuteMethod = canExecuteMethod; | |
} | |
public event EventHandler CanExecuteChanged | |
{ | |
add | |
{ | |
CommandManager.RequerySuggested += value; | |
} | |
remove | |
{ | |
CommandManager.RequerySuggested -= value; | |
} | |
} | |
public void RaiseCanExecuteChanged() | |
{ | |
CommandManager.InvalidateRequerySuggested(); | |
} | |
bool ICommand.CanExecute(object parameter) | |
{ | |
return !_isExecuting && CanExecute((T)parameter); | |
} | |
void ICommand.Execute(object parameter) | |
{ | |
_isExecuting = true; | |
try | |
{ | |
RaiseCanExecuteChanged(); | |
Execute((T)parameter); | |
} | |
finally | |
{ | |
_isExecuting = false; | |
RaiseCanExecuteChanged(); | |
} | |
} | |
public bool CanExecute(T parameter) | |
{ | |
if (_canExecuteMethod == null) | |
return true; | |
return _canExecuteMethod(parameter); | |
} | |
public void Execute(T parameter) | |
{ | |
_executeMethod(parameter); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment