gpt4 book ai didi

c# - MVVM 中异步命令的自动化测试

转载 作者:行者123 更新时间:2023-12-03 10:52:43 25 4
gpt4 key购买 nike

我有一个异步 Command类,像这样:

public AsyncDelegateCommand(Func<Task> execute, Func<bool> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}

public virtual bool CanExecute(object parameter)
{
if(executing)
return false;
if(canExecute == null)
return true;
return canExecute();
}

public async void Execute(object parameter) // Notice "async void"
{
executing = true;
CommandManager.InvalidateRequerySuggested();
if(parameter != null && executeWithParameter != null)
await executeWithParameter(parameter);
else if(execute != null)
await execute();
executing = false;
CommandManager.InvalidateRequerySuggested();
}

它是这样调用的:
FindProductCommand = new AsyncDelegateCommand(TryToFindProduct, () => CanFindProduct() && connector.HasConnection);

private async Task TryToFindProduct()
{
//code
}

当我进行单元测试时,它工作得很好,因为我会立即从任务中返回。

但是,在编写集成测试时,我遇到了麻烦。我无法等待 Execute , 因为它是 void ,我无法将其更改为 Task .我最终这样做了::/
findProductViewModel.FindProductCommand.Execute(null);
Thread.Sleep(2000);

var informationViewModel = findProductViewModel.ProductViewModel.ProductInformationViewModel;

Assert.AreEqual("AFG00", informationViewModel.ProductGroup);

这个测试有更好的解决方案吗? 也许取决于实际需要多长时间,并且不估计要等待多长时间。

最佳答案

您可以引用@StephenCleary 的一篇不错的博文:https://msdn.microsoft.com/en-us/magazine/dn630647.aspxasync void通常要避免,因此他为异步命令引入了一个新接口(interface)(及其基本实现):IAsyncCommand .该接口(interface)包含一个方法async Task ExecuteAsync(object parameter)您可以在测试中等待。

public interface IAsyncCommand : ICommand
{
Task ExecuteAsync(object parameter);
}

public abstract class AsyncCommandBase : IAsyncCommand
{
public abstract bool CanExecute(object parameter);
public abstract Task ExecuteAsync(object parameter);

public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

protected void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
}

这种异步命令的最简单实现如下所示:
public class AsyncCommand : AsyncCommandBase
{
private readonly Func<Task> _command;

public AsyncCommand(Func<Task> command)
{
_command = command;
}

public override bool CanExecute(object parameter)
{
return true;
}

public override Task ExecuteAsync(object parameter)
{
return _command();
}
}

但是您可以在链接的博客文章中找到更高级的变体。您可以使用 IAsyncCommand s 在你的代码中,所以你可以测试它们。您使用的 MVVM 框架也会很高兴,因为该接口(interface)基于 ICommand .

关于c# - MVVM 中异步命令的自动化测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45877941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com