我正在尝试对命令进行单元测试,但是由于它是异步命令,因此测试方法会在命令完成之前进入断言。我已经找到了解决此问题的方法,他们都在谈论创建我不想做的AsyncCommand接口等,因为我只需要等待命令进行单元测试即可。那么是否有另一种解决方案,它更简单并且不需要创建其他接口等?
这是我的Command类:
public class Command : ICommand
{
public void Execute(object parameter)
{
//exeute...
}
//other stuff....
}
那是经过测试的课程:
pubic class MyClass
{
private Command commandForTest;
public Command CommandForTest
{
get
{
if (commandForTest == null)
{
commandForTest = new Command(async (o) =>
{
if(someCondition)
await SomeMethod();
else
await AnotheMrthod();
});
}
return commandForTest;
}
}
}
这是测试方法:
[TestMethod]
public async Task Test()
{
MyClass myclass = new MyClass();
await Task.Run( () => myclass.CommandForTest.Execute());
//Assert....
}
答案 0 :(得分:4)
那么还有另一种解决方案,它更简单并且不需要创建其他接口等吗?
否,是的。还有另一种解决方案。 不更简单。最简单,最直接的解决方案是使用IAsyncCommand
interface。或一种AsyncCommand
实现,您的单元测试可以将ICommand
转换为(更易碎)。
但是,如果您想走艰难的路,那么可以,从技术上讲,您可以检测到async void
方法何时完成。您可以通过编写自己的SynchronizationContext
and listening to OperationStarted
and OperationCompleted
来实现。您还需要建立一个工作队列并编写一个处理该队列的主循环。
我有执行此操作的类型。它称为AsyncContext
and it is part of AsyncEx
。用法:
[TestMethod]
public void Test() // note: not async
{
MyClass myclass = new MyClass();
AsyncContext.Run(() =>
{
myclass.CommandForTest.Execute();
});
//Assert....
}
同样,我强烈建议您使用IAsyncCommand
。真正的问题是核心MVVM类型不足。因此,大多数人在虚拟机上使用IAsyncCommand
或MvxAsyncCommand
或AsyncCommand
或将命令逻辑作为async Task
方法公开。