【问题标题】:Unit test for web api action method responds while exceptionWeb api操作方法的单元测试在异常时响应
【发布时间】:2017-02-16 11:57:44
【问题描述】:

我正在尝试为 web api 操作方法编写一些单元测试,同时出现异常。所以下面我的操作方法

[Route("{userName}/{searchCriteria}")]
[HttpGet]
public IHttpActionResult Events(string accountNumber, string searchCriteria)
{
    try
    {
        bool isInputValid = _inputValidation.IsTrackingEventInputValid(accountNumber, searchCriteria);
        if (isInputValid)
        {
            return OK ("my data");
        }
        else
        {
            throw new ArgumentException();
        }
    }
    catch (ArgumentException ae)
    {
        return new ResponseMessageResult(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ExceptionHandlingMessages.InvalidArgumentException));
    }
    catch (Exception ex)
    {
        return new ResponseMessageResult(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ExceptionHandlingMessages.InternalServerError));
    }
}

我想检查响应状态代码并在发生异常时响应消息。但问题是,一旦我的执行命中ResponseMessageResult 代码,它就会抛出另一个ArgumentNullExceptionValue cannot be null.Parameter name: request。因为那个控制永远不会返回到我的单元测试方法。

我的单元测试方法为

[TestMethod]
public void Events()
{
    _mockInputValidation.Setup(x => x.IsTrackingEventInputValid(It.IsAny<string>(), It.IsAny<string>())).Returns(false);
    //act
    IHttpActionResult actionResult = _trackingEventController.Events(string.Empty, string.Empty);
    //assert
}

我也尝试输入[ExpectedException(type)],但没有多大帮助

我该如何解决这个问题

【问题讨论】:

  • 如果要测试catch块中的返回值,只需在_inputValidation.IsTrackingEventInputValid中抛出异常即可。我不记得实际的语法,但是将模拟更改为 _mockInputValidation.Setup(x =&gt; x.IsTrackingEventInputValid(It.IsAny&lt;string&gt;(), It.IsAny&lt;string&gt;())).Throws(new ArgumentException()); 应该可以让您获得第一个 ResponseMessageResult
  • 展示你如何新建控制器。很可能请求为空
  • 我会明确地质疑对动作方法进行单元测试的价值——它们的行为取决于许多外部框架设置。您最好尽量减少操作方法内部的行为(将其推到接口后面)并使用实际通过 HTTP 请求到达端点的验收测试进行端到端测试。
  • 我对单元测试控制器没有问题,但我会丢失 try/catch 块,只返回 ResponseMessageResult 而不会在同一方法中抛出和捕获。

标签: c# unit-testing asp.net-web-api


【解决方案1】:

重构您的代码以尽量避免在您的操作中引发异常。让异常处理程序/过滤器处理它们(横切关注点)。如果您没有为单元测试提供正确的请求消息,则可能会发生您最初的问题。

[Route("{userName}/{searchCriteria}")]
[HttpGet]
public IHttpActionResult Events(string accountNumber, string searchCriteria) {
    bool isInputValid = _inputValidation.IsTrackingEventInputValid(accountNumber, searchCriteria);
    if (isInputValid) {
        return Ok("my data");
    } else {
        return BadRequest(ExceptionHandlingMessages.InvalidArgumentException);
    }
}

然后针对特定的测试用例

[TestMethod]
public void IsTrackingEventInputValid_When_False_Should_Return_BadRequest() {
    //Arrange
    _mockInputValidation.Setup(x => x.IsTrackingEventInputValid(It.IsAny<string>(), It.IsAny<string>())).Returns(false);
    var expected = ExceptionHandlingMessages.InvalidArgumentException;
    //Act
    var actionResult = _trackingEventController.Events(string.Empty, string.Empty) as BadRequestErrorMessageResult;
    //Assert
    Assert.IsNotNull(actionResult);
    Assert.AreEqual(expected, actionResult.Message);
}

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2012-05-20
    • 2018-01-03
    相关资源
    最近更新 更多