如何用async方法对ViewModel进行单元测试
本文关键字:单元测试 ViewModel 何用 async 方法 | 更新日期: 2023-09-27 18:05:46
我不知道从哪里开始,但让我给你一个简短的想法,我在哪里,我想实现什么。我对MVVM上的单元测试非常陌生,并且在使用PRISM委托命令属性测试我所暴露的命令时遇到了困难。我的委托命令调用async方法,它必须等待,这样我才能得到实际的结果。下面是我要测试的方法调用的一个async方法。
async void GetTasksAsync()
{
this.SimpleTasks.Clear();
Func<IList<ISimpleTask>> taskAction = () =>
{
var result = this.dataService.GetTasks();
if (token.IsCancellationRequested)
return null;
return result;
};
IsBusyTreeView = true;
Task<IList<ISimpleTask>> getTasksTask = Task<IList<ISimpleTask>>.Factory.StartNew(taskAction, token);
var l = await getTasksTask; // waits for getTasksTask
if (l != null)
{
foreach (ISimpleTask t in l)
{
this.SimpleTasks.Add(t); // adds to ViewModel.SimpleTask
}
}
}
也是在我的VM中调用上面的async方法的命令
this.GetTasksCommand = new DelegateCommand(this.GetTasks);
void GetTasks()
{
GetTasksAsync();
}
现在我的Test Method变成了
[TestMethod]
public void Command_Test_GetTasksCommand()
{
MyViewModel.GetTaskCommand.Execute(); // this should populate ViewModel.SimpleTask
Assert.IsTrue(MyBiewModel.SimpleTask != null)
}
目前我得到的是我的ViewModel。SimpleTask = null这是因为它不等待异步方法完成。我知道在堆栈溢出中已经有一些相关的主题,但我找不到与我的delegatcommands相关的东西。
你的方法GetTasksAsync应该返回一个Task,这样你就可以等待它了
我推荐第九频道的这个系列节目,特别是这一集解释你的问题。
只是为了弄清楚:只需将GetTasksAsync的签名更改为
Task GetTasksAsync();
允许你这样做:
var t = GetAsync();
t.Wait();
Assert(...);
如果你真的想在单元测试中测试命令,而不是命令调用的实际方法,你可以在ViewModel中使用一个字段来存储等待的任务(不太干净),或者用这篇文章中描述的东西代替你的DelegateCommand:
更新:除了博客文章,考虑到你正在使用PRISM,你应该看看来自PRISM同一团队的Project Kona。他们实际上实现了DelegateCommand来支持AsyncHandlers