我不知道从哪里开始,但是让我简要介绍一下我在哪里以及我想要实现的目标。我对MVVM上的单元测试很陌生,并且很难测试我使用PRISM委托命令属性公开的命令。 我的委托命令调用必须等待的异步方法,以便我可以获得实际结果。下面是一个asyc方法,由我想测试的方法调用。
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中调用上面的异步方法的命令
this.GetTasksCommand = new DelegateCommand(this.GetTasks);
void GetTasks()
{
GetTasksAsync();
}
现在我的测试方法就像
[TestMethod]
public void Command_Test_GetTasksCommand()
{
MyViewModel.GetTaskCommand.Execute(); // this should populate ViewModel.SimpleTask
Assert.IsTrue(MyBiewModel.SimpleTask != null)
}
目前我得到的是我的ViewModel.SimpleTask = null这是因为它不等待异步方法完成。我知道堆栈溢出已经有一些相关的主题,但我找不到与DelegateCommands相关的东西。
答案 0 :(得分:9)
你的方法GetTasksAsync应该返回一个Task,你可以实际等待它。
我建议在Channel9上使用this series专门this episode解释您的问题。
只是说清楚:只需将GetTasksAsync的签名更改为
即可Task GetTasksAsync();
允许您这样做:
var t = GetAsync();
t.Wait();
Assert(...);
如果您真的想要在单元测试中测试命令而不是命令调用的实际方法,您可以使用ViewModel中的字段来存储任务(不是那么干净)或者用某个东西替换您的DelegateCommand如本文所述:Awaitable DelegateCommand
更新:除了博客文章并考虑到您正在使用PRISM,您应该看一下与PRISM在同一团队中的Project Kona。他们实际上实施了DelegateCommand to support AsyncHandlers