我的单元测试没有在我的控制器操作中捕获异常

时间:2016-08-02 09:17:34

标签: c# unit-testing async-await

我有一个单元测试,例如:

[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!");
}

但它始终击中最后Fail,即没有抛出异常。我已经开启了第一次机会异常并且可以看到它被抛出并且一直被重新抛出。它肯定一直冒出来。

注意:SO将此标记为

的可能副本

Unit testing async method for specific exception

这个问题是一个操作方法,但这个是一个问题解决方案,特别针对为什么catch没有被击中,即你知道怎么做,但却犯了一个常见的错误,忘记了这个动作是异步的 - 因为它们通常没有Async后缀 - 并且需要展开。

2 个答案:

答案 0 :(得分:3)

如果您的Put方法是异步任务方法,我怀疑它是基于您描述的问题,您可以通过制作签名异步任务来修改您的测试方法以适当地处理async / await。如果您的Put方法是异步任务,它将作为热门任务执行,但由于当前没有等待,因此您的单元测试线程会在实际引发异常之前继续。基本上,原始代码正在创建一个火灾和遗忘的场景。

[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!");
}

答案 1 :(得分:0)

Put操作方法是否异步?

如果是,那么您没有访问操作的结果,并且异常没有被“解包”。

如果r.ExecuteAsync(...)IHttpActionResult,或者在r.Wait();的调用下添加Put(...),您应该致电AggregateException

您可能还需要更改catch块以捕获login.html并进行检查。