如何使用 Visual studio 的 Fakes 框架存根异步方法?
How do you stub an async method using Visual studio's Fakes framework?
我需要存根的方法称为例如像这样:
List<DocumentInfo> documentInfosToDelete = await _documentInfoRepository.GetListByExternalIdAsync(
partyLegalEntity,
externalId,
type,
status);
这有效,但会生成编译器警告:“此异步方法缺少 'await' 运算符”等
testService.DocumentInfoRepos.GetListByExternalIdAsyncStringStringDocumentTypeDocumentStatus =
(async (a, b, c, d) =>
{
GetListByExternalIdAsyncCalled = true;
return new List<DocumentInfo>();
});
我想去掉这些警告,因为它们会淹没任何关于实际问题的警告。
返回新任务(...) 挂起。如果我正确理解我在 WWW 上找到的内容,Task.Run(...) 会做一些与我们正在使用的等待异步模式完全不同的事情。
怎么办?
返回 new Task(…)
挂起,因为这会创建一个未启动的 Task
。您可以做的是通过调用 Task.FromResult
:
创建一个已经完成的 Task
testService.DocumentInfoRepos.GetListByExternalIdAsyncStringStringDocumentTypeDocumentStatus =
(a, b, c, d) =>
{
GetListByExternalIdAsyncCalled = true;
return Task.FromResult(new List<DocumentInfo>());
};
此代码的行为与没有 await
的 async
方法相同,但不会产生警告。
@Klaus 问了一个很好的问题,因为,例如,在测试过程中,测试调用异步方法的代码在成功、错误和取消时的行为方式是很好的。 Task中定义如下:
- 任务Task.CompletedTask:属性,获取一个已经成功完成任务的任务
- Task Task.FromException(Exception): 方法,创建一个已完成但出现指定异常的任务。
- Task Task.FromCanceled(CancellationToken): 方法,使用指定的取消令牌创建因取消而完成的任务。
- TaskTask.FromResult(T):方法,获取一个已经成功完成任务的Task
- Task Task.FromException(Exception): 方法,创建一个已完成但出现指定异常的任务。
- Task Task.FromCanceled(CancellationToken): 方法,使用指定的取消令牌创建因取消而完成的任务。
这些方法和属性的实现方式如下:
public async Task JoeAsync()
{
await Task.CompletedTask;
}
public async Task JimAsync()
{
await Task.FromException(new NullReferenceException("Fake null reference"));
}
// Make sure cancelToken.IsCancellationRequested == true
public async Task JoeAsync(CancellationToken cancellationToken)
{
await Task.FromCanceled(cancellationToken);
}
public async Task<string> JanAsync()
{
return await Task.FromResult("Should complete successfully");
}
public async Task<string> JedAsync()
{
return await Task.FromException<string>(new NullReferenceException("Fake null reference"));
}
// Make sure cancelToken.IsCancellationRequested == true
public async Task<string> JanAsync(CancellationToken cancellationToken)
{
return await Task.FromCanceled<string>(cancellationToken);
}
测试上述方法的代码如下:
Task task;
var cancellationTokenSource = new CancellationTokenSource();
var cancelToken = cancellationTokenSource.Token;
cancellationTokenSource.Cancel();
task = this.JoeAsync();
Trace.Assert(task.IsCompleted);
Trace.Assert(task.IsCompletedSuccessfully);
task = this.JoeAsync(cancelToken);
Trace.Assert(task.IsCanceled);
Trace.Assert(cancelToken.IsCancellationRequested);
task = this.JimAsync();
Trace.Assert(task.IsFaulted);
Task<string> task2;
task2 = this.JanAsync();
Trace.Assert(task2.IsCompleted);
Trace.Assert(task2.IsCompletedSuccessfully);
task2 = this.JanAsync(cancelToken);
Trace.Assert(task2.IsCanceled);
Trace.Assert(cancelToken.IsCancellationRequested);
task2 = this.JedAsync();
Trace.Assert(task2.IsFaulted);
我需要存根的方法称为例如像这样:
List<DocumentInfo> documentInfosToDelete = await _documentInfoRepository.GetListByExternalIdAsync(
partyLegalEntity,
externalId,
type,
status);
这有效,但会生成编译器警告:“此异步方法缺少 'await' 运算符”等
testService.DocumentInfoRepos.GetListByExternalIdAsyncStringStringDocumentTypeDocumentStatus =
(async (a, b, c, d) =>
{
GetListByExternalIdAsyncCalled = true;
return new List<DocumentInfo>();
});
我想去掉这些警告,因为它们会淹没任何关于实际问题的警告。
返回新任务(...) 挂起。如果我正确理解我在 WWW 上找到的内容,Task.Run(...) 会做一些与我们正在使用的等待异步模式完全不同的事情。
怎么办?
返回 new Task(…)
挂起,因为这会创建一个未启动的 Task
。您可以做的是通过调用 Task.FromResult
:
Task
testService.DocumentInfoRepos.GetListByExternalIdAsyncStringStringDocumentTypeDocumentStatus =
(a, b, c, d) =>
{
GetListByExternalIdAsyncCalled = true;
return Task.FromResult(new List<DocumentInfo>());
};
此代码的行为与没有 await
的 async
方法相同,但不会产生警告。
@Klaus 问了一个很好的问题,因为,例如,在测试过程中,测试调用异步方法的代码在成功、错误和取消时的行为方式是很好的。 Task中定义如下:
- 任务Task.CompletedTask:属性,获取一个已经成功完成任务的任务
- Task Task.FromException(Exception): 方法,创建一个已完成但出现指定异常的任务。
- Task Task.FromCanceled(CancellationToken): 方法,使用指定的取消令牌创建因取消而完成的任务。
- TaskTask.FromResult(T):方法,获取一个已经成功完成任务的Task
- Task Task.FromException(Exception): 方法,创建一个已完成但出现指定异常的任务。
- Task Task.FromCanceled(CancellationToken): 方法,使用指定的取消令牌创建因取消而完成的任务。
这些方法和属性的实现方式如下:
public async Task JoeAsync()
{
await Task.CompletedTask;
}
public async Task JimAsync()
{
await Task.FromException(new NullReferenceException("Fake null reference"));
}
// Make sure cancelToken.IsCancellationRequested == true
public async Task JoeAsync(CancellationToken cancellationToken)
{
await Task.FromCanceled(cancellationToken);
}
public async Task<string> JanAsync()
{
return await Task.FromResult("Should complete successfully");
}
public async Task<string> JedAsync()
{
return await Task.FromException<string>(new NullReferenceException("Fake null reference"));
}
// Make sure cancelToken.IsCancellationRequested == true
public async Task<string> JanAsync(CancellationToken cancellationToken)
{
return await Task.FromCanceled<string>(cancellationToken);
}
测试上述方法的代码如下:
Task task;
var cancellationTokenSource = new CancellationTokenSource();
var cancelToken = cancellationTokenSource.Token;
cancellationTokenSource.Cancel();
task = this.JoeAsync();
Trace.Assert(task.IsCompleted);
Trace.Assert(task.IsCompletedSuccessfully);
task = this.JoeAsync(cancelToken);
Trace.Assert(task.IsCanceled);
Trace.Assert(cancelToken.IsCancellationRequested);
task = this.JimAsync();
Trace.Assert(task.IsFaulted);
Task<string> task2;
task2 = this.JanAsync();
Trace.Assert(task2.IsCompleted);
Trace.Assert(task2.IsCompletedSuccessfully);
task2 = this.JanAsync(cancelToken);
Trace.Assert(task2.IsCanceled);
Trace.Assert(cancelToken.IsCancellationRequested);
task2 = this.JedAsync();
Trace.Assert(task2.IsFaulted);