如何为使用StatusCode 404抛出HttpException的Action编写单元测试

时间:2014-07-13 09:27:18

标签: asp.net-mvc-4 unit-testing

我在控制器中有以下操作,该操作会抛出 HttpException ,状态代码为 404

public async Task<ActionResult> Edit(int id)
{
    Project proj = await _service.GetProjectById(id);
    if( proj == null)
    {
        throw new HttpException(404, "Project not found.");
    }
}

为了测试这个场景,我编写了下面的测试用例,其中我捕获了AggregationException并重新抛出了InnerException,它被期望为HttpException:

[TestMethod]
[ExpectedException(typeof(HttpException),"Project not found.")]
public void Edit_Project_Load_InCorrect_Value()
{
    Task<ActionResult> task = _projectController.Edit(3);
    try
    {
        ViewResult result = task.Result as ViewResult;
        Assert.AreEqual("NotFound", result.ViewName, "Incorrect Page title");
    }
    catch (AggregateException ex)
    {
        throw ex.InnerException;
    }
}

此测试成功运行并返回ExpectedException。我在这里有两个问题:

  1. 这是编写单元测试的正确方法还是有更多 亲切的测试方式。
  2. 这是否可以检查单元测试 该用户获得了正确的错误页面(在这种情况下为NotFound)。

1 个答案:

答案 0 :(得分:1)

有一种更好的方法来测试它。我们编写了一个名为AssertHelpers.cs的类,其中包含此方法。这比ExpectedException更好的原因是ExpectedException实际上没有验证它被抛出,它只是允许测试在抛出时通过。 例如,如果您将404代码更改为200,则测试不会失败。

public static void RaisesException<TException>(Action dataFunction, string exceptionIdentifier = null)
{
    bool threwException = false;

    try
    {
        dataFunction();
    }
    catch (Exception e)
    {
        threwException = true;
        Assert.IsInstanceOfType(e, typeof(TException));
        if (exceptionIdentifier != null)
            Assert.AreEqual(exceptionIdentifier, e.Message);
    }

    if (!threwException)
        Assert.Fail("Expected action to raise exception with message: " + exceptionIdentifier);
}