测试DelegateCommand异步,无需公开处理程序

时间:2018-07-11 14:42:53

标签: c# wpf mvvm prism

使用 Prism 中的 DelegateCommand ,由于FromAsyncHanlder已从版本 6.3 中删除,因此不再可能等待命令执行。

对于单元测试,建议按照以下说明进行移植,

Task MyHandler() {...}
DelegateCommand myCommand = DelegateCommand.FromAsyncHandler(MyHandler);
/// in test:
await myCommand.Execute();

将其更改为

DelegateCommand myCommand = new DelegateCommand(async () => await MyHandler());
/// in test:
await MyHandler();

但是,这要求命令处理程序(MyHandler)公开,这否定了使用命令模式的封装优点。

我知道我可以使用/创建其他命令实现,但是我喜欢DelegateCommand,因为它是Prism的一部分并定期维护。

是否有更好的方法使用DelegateCommand测试异步命令?

2 个答案:

答案 0 :(得分:2)

  

是否有更好的方法使用DelegateCommand测试异步命令?

不是。由于DelegateCommand类不会公开任何异步和等待的方法,因此恐怕您无法等待命令本身。

您可以使用MyHandler()方法internal并将InternalsVisibleToAttribute应用于您的程序集:

[assembly: InternalsVisibleTo("UnitTests")] 

也许更好。您的其他选择基本上是使方法public或使用支持ICommand / async的另一个await实现。

答案 1 :(得分:0)

您对以下方法有何看法:

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();
    }
}

可以像测试它一样

await myCommand.ExecuteAsync();