Reputation: 666
Using the DelegateCommand within Prism it is no longer possible to await the command execution since FromAsyncHanlder was removed from version 6.3.
For unit testing the recommendation is to port as below, so if you have
Task MyHandler() {...}
DelegateCommand myCommand = DelegateCommand.FromAsyncHandler(MyHandler);
/// in test:
await myCommand.Execute();
change it to
DelegateCommand myCommand = new DelegateCommand(async () => await MyHandler());
/// in test:
await MyHandler();
This however requires the command handler (MyHandler) to be made public which negates the encapsulation benefits of using the command pattern.
I know that I can use/create other command implementations but I like DelegateCommand as it is part of Prism and regularly maintained.
Is there a better way of testing async commands using the DelegateCommand?
Upvotes: 2
Views: 1542
Reputation: 1
What would you say about following approach:
public class AsyncDelegateCommand : DelegateCommand
{
private Func<Task> executeAction;
public AsyncDelegateCommand(Func<Task> executeAction) : base(async () => { await executeAction(); })
{
this.executeAction = executeAction;
}
public async Task ExecuteAsync()
{
if (CanExecute())
{
try
{
IsActive = true;
await executeAction();
}
finally
{
IsActive = false;
}
}
RaiseCanExecuteChanged();
}
}
And it can be tested just like:
await myCommand.ExecuteAsync();
Upvotes: 0
Reputation: 169400
Is there a better way of testing async commands using the DelegateCommand?
Not really. Since the DelegateCommand
class doesn't expose any async and awaitable methods, you cannot await the command itself I am afraid.
You could make the MyHandler()
method internal
and apply the InternalsVisibleToAttribute to your assembly:
[assembly: InternalsVisibleTo("UnitTests")]
Maybe that's a bit better. Your other options are basically to make the method public
or use another ICommand
implementation that supports async
/await
.
Upvotes: 2