所以我有一些代码
Task.Factory.StartNew(() => this.listener.Start()).ContinueWith(
(task) =>
{
if (task.IsCompleted)
{
this.status = WorkerStatus.Started;
this.RaiseStatusChanged();
this.LogInformationMessage("Worker Started.");
}
});
Run Code Online (Sandbox Code Playgroud)
当我测试时,我正在模拟所有依赖对象(namley this.listener.Start()).问题是测试在ContinueWith被调用之前完成执行.当我调试时,由于我单步执行代码的额外延迟,它被称为罚款.
那么我怎么能 - 从不同程序集中的测试代码 - 确保代码在我的测试遇到其断言之前运行?
我可以使用Thread.Sleep ......但这似乎是一种真正的hacky方式.
我想我正在寻找Thread.Join的Task版本.
我尝试为View Model编写单元测试,但在尝试验证ICommand调用异步方法两次时,我遇到了问题.
我使用Moq作为我的依赖项.我像这样设置了异步方法.
this.communicationServiceFake
.Setup(x => x.WriteParameterAsync(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsyncIncomplete();
Run Code Online (Sandbox Code Playgroud)
Extension ReturnsAsyncIncomplete不会立即返回await关键字,基本上类似于以下内容:Async/Await和代码覆盖率
我使用自己的TaskSheduler来确保在Task.Factory.StartNew返回之前竞争方法.
Task.Factory.StartNew(() => viewModel.Command.Execute(null),
CancellationToken.None, TaskCreationOptions.None, new CurrentThreadTaskScheduler ());
Run Code Online (Sandbox Code Playgroud)
基本上,CurrentThreadTaskScheduler来自这里:等到所有任务在单元测试中完成并且看起来像这样:
public class CurrentThreadTaskScheduler : TaskScheduler
{
protected override void QueueTask(Task task)
{
this.TryExecuteTask(task);
}
protected override bool TryExecuteTaskInline(Task task, bool wasPreviouslyQueued)
{
return this.TryExecuteTask(task);
}
protected override IEnumerable<Task> GetScheduledTasks()
{
yield break;
}
}
Run Code Online (Sandbox Code Playgroud)
命令会调用以下代码:
await this.communicationService.WriteParameterAsync("Parameter1", true);
await this.communicationService.WriteParameterAsync("Parameter2", true);
Run Code Online (Sandbox Code Playgroud)
然后验证:
this.communicationServiceFake
.Verify(t => t.WriteParameterAsync("Parameter1", true), Times.Once);
this.communicationServiceFake
.Verify(t => t.WriteParameterAsync("Parameter2", true), Times.Once);
Run Code Online (Sandbox Code Playgroud)
有时它说第二次电话没有发生.如果我用ThreadSleep替换我的Task.Factory.StartNew以确保一切都完成,所有工作正常,即使它确实注意似乎正确地延迟我的单元测试不必要.
为什么我的CurrentThreadTaskScheduler允许Task.Factory.StartNew在我的Command.Execute完成之前返回?