假设我有以下类和它所依赖的接口(interface):
public class MyController
{
private IRepository _repository;
public MyController(IRepository repository)
{
_repository = repository;
}
public async Task MethodUnderTest(int someId)
{
var o = await _repository.FindById(someId);
// update o
await _repository.Commit();
}
}
public interface IRepository
{
Task Commit();
}
当我对该方法进行单元测试时,我可以执行以下操作(使用 xUnit 和 Rhino Mocks):
[Fact]
public async Task MyTest()
{
IRepository repositoryStub = MockRepository.GenerateStub<IRepository>();
MyController controller = new MyController(repositoryStub);
await controller.MethodUnderTest(1);
}
这将失败并出现 System.NullReferenceException:对象引用未设置为对象的实例。
使用以下 StackTrace:
UnitTest.MyController.<MethodUnderTest>d__0.MoveNext() in
\UnitTest\Class1.cs:line 35
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at \UnitTest\Class1.cs:line 20
发生此错误是否正确,因为 Commit()
返回 null
以及为异步/等待调用生成的状态机 MoveNext()
在 null
上?
我可以通过做类似的事情来解决这个问题:
repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult<bool>(true);
但这感觉有点奇怪..我可以使用任何T
对于 FromResult<T>
并且测试将运行。我找不到 FromResult
将返回非泛型 Task
的方法.
我对 T
使用什么重要吗? ?或者我应该用其他方式解决这个问题吗?
最佳答案
您需要返回; async Task
方法永远不能返回 null
.
T
没关系。你可以声明一个 static readonly Task SuccessTask = Task.FromResult<object>(null);
如果你愿意,可以作为辅助常量。我有 similar constants在我的 AsyncEx 库中。
关于c# - 异步单元测试中的 stub 任务返回方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13991956/