NUnit的异步测试异常断言 [英] Nunit async test exception assertion
问题描述
我有一个控制器 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");
}
结果
测试通过
问题 -
- 为什么Assert.Throws不能处理的Htt presponseException,当时的ExpectedException呢?
- 我不想只是测试异常。我想断言的响应的状态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屋!