存根任务异步单元测试方法返回 [英] Stubbing Task returning method in async unit test

查看:143
本文介绍了存根任务异步单元测试方法返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有以下的类和接口这取决于:

Let's say I have the following class and an interface it depends on:

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和犀牛制品):

When I unit test this method I can do the following (using xUnit and Rhino Mocks):

[Fact]
public async Task MyTest()
{
    IRepository repositoryStub = MockRepository.GenerateStub<IRepository>();

    MyController controller = new MyController(repositoryStub);

    await controller.MethodUnderTest(1);
}

这失败,出现的 System.NullReferenceException:未将对象引用设置到对象的实例

通过下面的堆栈跟踪:

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

是不是正确的,出现这种错误,因为提交()收益和异步产生的statemachine /呼叫等待的MoveNext()

Is it correct that this error occurs because the Commit() returns null and the statemachine generated for the async/await calls MoveNext() on a null?

我可以做这样的事情解决这个问题:

I can fix this by doing something like:

repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult<bool>(true);

但这种感觉有点怪怪的。我可以使用任何 T FromResult&LT; T&GT; 和试验会跑。我无法找到一个 FromResult 方法将返回一个非通用工作

But this feels a little strange.. I can use any T for FromResult<T> and the test will run. I can't find a FromResult method that will return a non-generic Task.

不要紧,我用了 T ?或者我应该这样解决一些其他的方式?

Does it matter what I use for T? Or should I fix this some other way?

推荐答案

您将需要返回的东西; 异步任务方法永远不能返回

You will need to return something; async Task methods cannot ever return null.

T 无所谓。你可以声明静态只读任务SuccessTask = Task.FromResult&LT;对象&gt;(NULL); ,如果恒你想要一个帮手。我有类似的常量在我AsyncEx库的。

The T doesn't matter. You could declare a static readonly Task SuccessTask = Task.FromResult<object>(null); as a helper constant if you want. I have similar constants in my AsyncEx library.

这篇关于存根任务异步单元测试方法返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆