NUnit的异步测试异常断言 [英] Nunit async test exception assertion

查看:254
本文介绍了NUnit的异步测试异常断言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制器 UserController的这个动作

I have a controller UserController with this action

// GET /blah
public Task<User> Get(string domainUserName)
{
        if (string.IsNullOrEmpty(domainUserName))
        {
            throw new ArgumentException("No username specified.");
        }

        return Task.Factory.StartNew(
            () =>
                {
                    var user = userRepository.GetByUserName(domainUserName);
                    if (user != null)
                    {
                        return user;
                    }

                    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("{0} - username does not exist", domainUserName)));
                });
}

我试图写,我抛出一个异常404的情况下进行测试。

I am trying to write a test for the case where I throw a 404 exception.

下面是我都试过了,与输出 -

Here is what I have tried, with the output -

1)

[Test]
public void someTest()
{
        var mockUserRepository = new Mock<IUserRepository>();
        mockUserRepository.Setup(x => x.GetByUserName(It.IsAny<string>())).Returns(default(User));
    var userController = new UserController(mockUserRepository.Object) { Request = new HttpRequestMessage() };

    Assert.That(async () => await userController.Get("foo"), Throws.InstanceOf<HttpResponseException>());
}

结果
测试失败

  Expected: instance of <System.Web.Http.HttpResponseException>
  But was:  no exception thrown

2)

[Test]
public void someTest()
{
        var mockUserRepository = new Mock<IUserRepository>();
        mockUserRepository.Setup(x => x.GetByUserName(It.IsAny<string>())).Returns(default(User));
    var userController = new UserController(mockUserRepository.Object) { Request = new HttpRequestMessage() };

    var httpResponseException = Assert.Throws<HttpResponseException>(() => userController.Get("foo").Wait());
    Assert.That(httpResponseException.Response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}

结果
测试失败

  Expected: <System.Web.Http.HttpResponseException>
  But was:  <System.AggregateException> (One or more errors occurred.)

3)

[Test]
public void someTest()
{
        var mockUserRepository = new Mock<IUserRepository>();
        mockUserRepository.Setup(x => x.GetByUserName(It.IsAny<string>())).Returns(default(User));
    var userController = new UserController(mockUserRepository.Object) { Request = new HttpRequestMessage() };

    var httpResponseException = Assert.Throws<HttpResponseException>(async () => await userController.Get("foo"));
    Assert.That(httpResponseException.Response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}

结果
测试失败

  Expected: <System.Web.Http.HttpResponseException>
  But was:  null

4)

[Test]
[ExpectedException(typeof(HttpResponseException))]
public async void ShouldThrow404WhenNotFound()
{            var mockUserRepository = new Mock<IUserRepository>();
        mockUserRepository.Setup(x => x.GetByUserName(It.IsAny<string>())).Returns(default(User));

    var userController = new UserController(mockUserRepository.Object) { Request = new HttpRequestMessage() };

    var task = await userController.Get("foo");
}

结果
测试通过

问题 -


  1. 为什么Assert.Throws不能处理的Htt presponseException,当时的ExpectedException呢?

  2. 我不想只是测试异常。我想断言的响应的状态code。什么是做到这一点的方式呢?

对这些行为及其原因(S)的任何对比就太棒了!

Any comparision on these behaviour and its cause(s) would be great!

推荐答案

您所看到的异步无效由于问题

You're seeing problems due to async void.

在特定的:

1)异步()=&GT;等待userController.Get(富)转换成 TestDelegate ,返回无效 ,所以你的拉姆达前pression被视为异步无效。因此,测试运行将开始执行拉姆达而不是等待它完成。前获取拉姆达返回完成(因为它是异步),并测试运行发现它返回没有例外。

1) async () => await userController.Get("foo") is converted into TestDelegate, which returns void, so your lambda expression is treated as async void. So the test runner will begin executing the lambda but not wait for it to complete. The lambda returns before Get completes (because it's async), and the test runner sees that it returned without an exception.

2)等待包裹任何异常在 AggregateException

2) Wait wraps any exceptions in an AggregateException.

3)再次,异步拉姆达被视为异步无效,所以测试运行不候它的完成。

3) Again, the async lambda is being treated as async void, so the test runner is not waiting for its completion.

4)我建议你做这个异步任务,而不是异步无效,但在这种情况下,测试运行没有等待完成,从而看到了例外。

4) I recommend you make this async Task rather than async void, but in this case the test runner does wait for completion, and thus sees the exception.

根据这个bug报告,对于这NUnit的下一版本来修复。在此期间,你可以建立自己的 ThrowsAsync 方法;一个<一个href=\"http://stackoverflow.com/questions/14084923/how-to-handle-exceptions-thrown-by-tasks-in-xunit-nets-assert-throwst\">example为的xUnit是这里。

According to this bug report, there is a fix for this coming in the next build of NUnit. In the meantime, you can build your own ThrowsAsync method; an example for xUnit is here.

这篇关于NUnit的异步测试异常断言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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