如何对Webapi控制器进行单元测试发回错误

时间:2019-05-09 14:46:55

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

我有以下控制器方法:

public IHttpActionResult GetAttractions([FromUri] SearchAttractionRequest request)
{
        try
        {
            var requestParameterType = request.RequestType();

            var searchResultModel = _attractionService.GetAttractions(request);

            return TransformListToResult(searchResultModel.Results, request.PerPage, searchResultModel.TotalItemCount, searchResultModel.GeneratedQuery);
        }
        catch (Exception ex)
        {
          //  return Content(HttpStatusCode.BadRequest, "Any object");
          //  return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message));
        }
}

在进行调用request.RequestType()时,如果传入的参数无效,则将引发参数异常,并且代码最终将在catch块中。我有一个要编写的单元测试:

[Test]
public void Given_Mixed_Parameters_Expect_Error()
{
        var invalidQuery = new SearchAttractionRequest
        {
            Category = Guid.NewGuid().ToString() + "|a catgeory|" + Guid.NewGuid().ToString(),
            Genre = "",
            Region = ""
        };

        var attractionServiceMock = Mock.Of<IAttractionService>();

        var sut = new AttractionsApiController(attractionServiceMock);

        Action act = () => sut.GetAttractions(invalidQuery);

        act.ShouldThrow<HttpResponseException>();
}

基本上,我想测试一下,当我发送无效的参数时,我会得到错误响应。因此,我需要从api方法发送回什么信息,以及在测试中需要做些什么以测试错误。目前,我在测试中遇到错误,因为预期的错误是参数异常,这是正确的,但我想模仿客户端返回的内容。

我是否需要在测试中执行以下操作:

as OkNegotiatedContentResult<SomeObject>;

2 个答案:

答案 0 :(得分:1)

我相信您可以使用以下内容:

var attractionServiceMock = Mock.Of<IAttractionService>();

var sut = new AttractionsApiController(attractionServiceMock);

var result = sut.GetAttractions(invalidQuery) as BadRequestErrorMessageResult;
Assert.IsNotNull(result);

答案 1 :(得分:1)

您无法为将模仿客户端收到的内容的控制器编写准确的测试。这是因为从设计上讲,控制器只是具有返回某些结果的方法的类。从技术上讲,它不能确定客户收到什么。

例如,如果您调用抛出未处理的ArgumentException的方法,则其他中间件将确定客户端应收到500响应。控制器没有这样做。

或者,控制器可能返回ViewResult。客户端没有获取ViewResult-它获取HTML。控制器无法确定HTML将是什么。

在为控制器编写单元测试时,请将其视为另一个类。您只是在测试它是否返回了预期的结果。

如果控制器抛出未处理的ArgumentException,则可以对此进行测试。 如果您处理ArgumentException并返回

Content(HttpStatusCode.BadRequest, "Any object");`

您可以这样做:

var result = (NegotiatedContentResult<string>)controller.GetResult();
Assert.AreEqual(HttpStatusCode.BadRequest, result.StatusCode);