这取决于您试图测试什么:
- 测试
RelayCommand
是否正确连接并调用了您的async
方法?
或者
- 测试
Async
方法逻辑是否正确?
1. 测试RelayCommand触发器
1.a 使用外部依赖进行验证
根据我的个人经验,最简单的方法是测试触发器是否已正确连接以执行命令,然后测试您的类是否按预期与其他外部类交互。例如:
private async void ExecuteLoadJobCommandAsync()
{
await GetData(...);
}
private async void GetData(...)
{
var data = await _repo.GetData();
Jobs.Add(data);
}
测试你的仓库是否被调用相当容易。
public void TestUsingExternalDependency()
{
_repo.Setup(r => r.GetData())
.Returns(Task.Run(() => 5))
.Verifiable();
_vm.LoadJobCommand.Execute(null);
_repo.VerifyAll();
}
有时我甚至会这样做,以免尝试处理所有东西:
[Test]
public void TestUsingExternalDependency()
{
_repo.Setup(r => r.GetData())
.Returns(() => { throw new Exception("TEST"); })
.Verifiable();
try
{
_vm.LoadJobCommand.Execute(null);
}
catch (Exception e)
{
e.Message.Should().Be("TEST");
}
_repo.VerifyAll();
}
1.b 使用调度程序
另一种选择是使用调度程序,并使用它来安排任务。
public interface IScheduler
{
void Execute(Action action);
}
public class ThreadPoolScheduler : IScheduler
{
public void Execute(Action action)
{
Task.Run(action);
}
}
public class ImmediateScheduler : IScheduler
{
public void Execute(Action action)
{
action();
}
}
然后在您的 ViewModel 中
public ViewModelUnderTest(IRepository repo, IScheduler scheduler)
{
_repo = repo;
_scheduler = scheduler;
LoadJobCommand = new RelayCommand(ExecuteLoadJobCommandAsync);
}
private void ExecuteLoadJobCommandAsync()
{
_scheduler.Execute(GetData);
}
private void GetData()
{
var a = _repo.GetData().Result;
Jobs.Add(a);
}
和你的测试
[Test]
public void TestUsingScheduler()
{
_repo.Setup(r => r.GetData()).Returns(Task.Run(() => 2));
_vm = new ViewModelUnderTest(_repo.Object, new ImmediateScheduler());
_vm.LoadJobCommand.Execute(null);
_vm.Jobs.Should().NotBeEmpty();
}
2. 测试GetData
逻辑
如果您想测试获取GetData()
逻辑甚至是ExecuteLoadJobCommandAsync()
逻辑。那么你应该将要测试的方法设置为内部方法,并将你的程序集标记为InternalsVisibleTo
,以便您可以直接从测试类中调用这些方法。
AsyncCommand
(基本上是RelayCommandAsync
的实现),它提供了一个public async Task ExecuteAsync(object parameter)
,您可以在其上等待。 - Scott Chamberlain