我有一个控制器 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 thrown2)
[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: null4)
[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"); }结果测试通过
问题 -
对这些行为及其原因(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 方法;一个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的异步测试异常断言
发布评论