[英]My unit test is not catching an exception within my controller action
I have a unit test, something like: 我有一个单元测试,类似于:
[Test]
public void ThingController__Put__when_thing_is_invalid__then__throws()
{
var controller = this.CreateThingController();
try
{
var r = controller.Put("thing1", this.CreateInvalidThing());
}
catch(HttpResponseException hrex) when (hrex.Response.StatusCode == HttpStatusCode.BadRequest)
{
return; // implicit pass.
}
catch(Exception ex)
{
Assert.Fail($"Wrong exception {ex.GetType().Name}");
}
Assert.Fail("No exception thrown!");
}
But it always hits the last Fail
, ie no exception is thrown. 但是它总是命中最后一个
Fail
,即不会引发异常。 I have turned on first chance exceptions and can see it being thrown and is rethrown all the way up. 我打开了第一次机会异常,可以看到它被抛出并被重新抛出。 It definitely is bubbling all the way up.
它肯定一直在冒泡。
Note: SO flagged this as a possible duplicate of 注意:因此将其标记为可能的重复项
Unit testing async method for specific exception 针对特定异常的单元测试异步方法
That question is a how-to but this one is a problem-solution, specifically for why a catch
is not being hit, ie you know how, but made a common mistake forgetting that the action is async - because they normally don't have Async
suffix - and needs unwrapping. 这个问题是一个解决方法,但是这个问题是一个解决问题的方法,专门针对为何未击中
catch
,即您知道如何,但却犯了一个常见的错误,忘记了动作是异步的,因为它们通常没有Async
后缀-需要解包。
If your Put method is an async Task method, which I suspect it is based on the issue you're describing you can modify your test method to appropriately handle async/await by making the signature async Task. 如果您的Put方法是异步Task方法,我怀疑它是基于您所描述的问题,则可以通过使签名异步Task来修改测试方法以适当地处理async / await。 If your Put method is async task, it is executing as a hot task but since it is not being awaited currently your unit test thread continues on before your exception is actually raised.
如果您的Put方法是异步任务,则它作为一项热门任务执行,但由于当前尚未等待,因此您的单元测试线程将继续运行,直到实际引发异常。 Essentially the original code is creating a fire and forget scenario.
从本质上讲,原始代码创建了一种“放火烧了”的场景。
[Test]
public async Task ThingController__Put__when_thing_is_invalid__then__throws()
{
var controller = this.CreateThingController();
try
{
var r = await controller.Put("thing1", this.CreateInvalidThing());
}
catch(HttpResponseException hrex) when (hrex.Response.StatusCode == HttpStatusCode.BadRequest)
{
return; // implicit pass.
}
catch(Exception ex)
{
Assert.Fail($"Wrong exception {ex.GetType().Name}");
}
Assert.Fail("No exception thrown!");
}
Is the Put
action method asynchronous? Put
操作方法是异步的吗?
If so, then you are not accessing the result of the action and the exception is not being 'unwrapped'. 如果是这样,则您将无法访问该操作的结果,并且该异常不会被“展开”。
You should either be calling r.ExecuteAsync(...)
if its an IHttpActionResult
, or adding r.Wait();
您应该调用
r.ExecuteAsync(...)
如果它是IHttpActionResult
,或者添加r.Wait();
under the call to Put(...)
. 在对
Put(...)
的调用下。
You may also need to alter your catch block to catch AggregateException
and inspect it. 您可能还需要更改catch块以捕获
AggregateException
并对其进行检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.