c# – 如何单元测试在MVVM中调用异步方法的DelegateCommand

c# – 如何单元测试在MVVM中调用异步方法的DelegateCommand,第1张

概述我是新的单元测试MVVM和使用PRISM在我的项目.我正在对我们当前的项目进行单元测试,没有运气在线查找资源,告诉我如何测试调用异步方法的DelegateCommand.这是对我的帖子 – How to Unit Test a ViewModel with async method.的后续问题,关于如何在MVVM中单元测试异步方法,并回答说可以使用异步TestMethod测试公共方法.只有当我想测 我是新的单元测试MVVM和使用PRISM在我的项目.我正在对我们当前的项目进行单元测试,没有运气在线查找资源,告诉我如何测试调用异步方法的DelegateCommand.这是对我的帖子 – How to Unit Test a ViewModel with async method.的后续问题,关于如何在MVVM中单元测试异步方法,并回答说可以使用异步TestMethod测试公共方法.只有当我想测试的方法是公共方法时,这种情况才会起作用.

问题是我想测试我的DelegateCommand,因为这是我想在其他类上公开的唯一公开细节,其他的都是私有的.我可以将我的私有方法公开,但我永远不会这样做,因为它是一个糟糕的设计.我不知道如何去做 – 代表委员会需要测试,还有其他一些工作呢?我有兴趣知道别人怎么做,不知何故让我走上正确的道路.

这是我的代码

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                }            }        }

这里也是我的虚拟机中调用上述异步方法的命令

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这是因为它不等待异步方法完成.

解决方法 我写了一个AsyncCommand类,它从Execute方法返回一个Task对象.然后,您需要明确实现ICommand.Execute,等待Execute实现中的Task:
public class AsyncCommand : ICommand{    public event EventHandler CanExecuteChanged;    public Func<Task> ExecutedHandler { get; private set; }    public Func<bool> CanExecuteHandler { get; private set; }    public AsyncCommand(Func<Task> executedHandler,Func<bool> canExecuteHandler = null)    {        if (executedHandler == null)        {            throw new ArgumentNullException("executedHandler");        }        this.ExecutedHandler = executedHandler;        this.CanExecuteHandler = canExecuteHandler;    }    public Task Execute()    {        return this.ExecutedHandler();    }    public bool CanExecute()    {        return this.CanExecuteHandler == null || this.CanExecuteHandler();    }    public voID RaiseCanExecuteChanged()    {        if (this.CanExecuteChanged != null)        {            this.CanExecuteChanged(this,new EventArgs());        }    }    bool ICommand.CanExecute(object parameter)    {        return this.CanExecute();    }    async voID ICommand.Execute(object parameter)    {        await this.Execute();    }}

然后,您可以将异步任务返回方法传递给命令类:

public class viewmodel{    public AsyncCommand AsyncCommand { get; private set; }    public bool Executed { get; private set; }    public viewmodel()    {        Executed = false;        AsyncCommand = new AsyncCommand(Execute);    }    private async Task Execute()    {        await(Task.Delay(1000));        Executed = true;    }}

在单元测试中,您只需等待Execute方法:

[TestMethod]public async Task TestAsyncCommand(){    var viewmodel = new viewmodel();    Assert.IsFalse(viewmodel.Executed);    await viewmodel.AsyncCommand.Execute();    Assert.IsTrue(viewmodel.Executed);}

另一方面,UI将调用明确实现的ICommand.Execute方法,该方法负责等待任务.

(*)在此期间,我注意到,如果遵循常见的命名约定,任务返回方法实际上应该被命名为ExecuteAsync.

总结

以上是内存溢出为你收集整理的c# – 如何单元测试在MVVM中调用异步方法的DelegateCommand全部内容,希望文章能够帮你解决c# – 如何单元测试在MVVM中调用异步方法的DelegateCommand所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1239082.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存