【问题标题】:How to test my ASP.NET Core 2.2 Web API GET IActionResult that returns Ok(object)?如何测试返回 Ok(object) 的 ASP.NET Core 2.2 Web API GET IActionResult?
【发布时间】:2020-08-26 09:09:15
【问题描述】:

在我的 Web API 中,我有一个简单的控制器操作:

[HttpGet]
[Route("[action]")]
public IActionResult GetApiStatus(string token)
{
    if (_token != token)
    {
        return StatusCode(401);
    }

    StatusModel status = _vesselUpdating.GetUpdatingStatus();

    return Ok(status);
}

并且操作返回StatusModel 类型的对象。我无法管理如何测试它的返回状态。

我的测试方法如下:

[Theory]
[InlineData("wrong_token", StatusCodes.Status401Unauthorized)]
[InlineData("test_token", StatusCodes.Status200OK)]
[InlineData("", StatusCodes.Status401Unauthorized)]
[InlineData(null, StatusCodes.Status401Unauthorized)]
public void Get_GetAnyAction_WithVariusTokens_ReturnsCorrectStatusCode(string token, int code)
{
    _vesselUpdatingMock.Setup(v => v.GetUpdatingStatus()).Returns(_sampleStatusModel);
    IActionResult result;

    result = _updatesController.GetApiStatus(token);
    StatusCodeResult resultGetApiStatus = result as StatusCodeResult;

    Assert.Equal(code, resultGetApiStatus.StatusCode);
}

在调试时

result = _updatesController.GetApiStatus(token);

IActionResultStatusCode 属性是 200,但只有 DeclaredType 的属性是 null

当断言时,最后我有我的resultGetApiStatus null

我没有找到类似的例子。如何正确投影result

重要编辑:

我发现只有this approach,这不能解决我的问题,关于各种情况[Theory],并不是我所有的其他操作都返回ObjectResult,其中一些只返回StatusCode。有和没有ObjectResult 的操作是否有任何通用方法?还是应该使用不同的测试?

【问题讨论】:

    标签: c# unit-testing asp.net-core xunit


    【解决方案1】:

    这种挫败感不仅是你拥有的。

    OkObjectResult 不继承自 StatusCodeResult,所以

    StatusCodeResult resultGetApiStatus = result as StatusCodeResult;
    

    正确地返回 null。

    见:https://github.com/aspnet/Mvc/issues/7134

    您应该能够强制使用IStatusCodeActionResult

    https://github.com/dotnet/aspnetcore/blob/a410ed460140a55dd699e83d978b798de48802fb/src/Mvc/Mvc.Core/src/StatusCodeResult.cs#L32 但是,我不确定它附带哪个版本(2.1?)

    [Theory]
    [InlineData("wrong_token", StatusCodes.Status401Unauthorized)]
    [InlineData("test_token", StatusCodes.Status200OK)]
    [InlineData("", StatusCodes.Status401Unauthorized)]
    [InlineData(null, StatusCodes.Status401Unauthorized)]
    public void Get_GetAnyAction_WithVariusTokens_ReturnsCorrectStatusCode(string token, int code)
    {
        _vesselUpdatingMock.Setup(v => v.GetUpdatingStatus()).Returns(_sampleStatusModel);
    
        var result = _updatesController.GetApiStatus(token);
        var resultGetApiStatus = result as IStatusCodeActionResult;
    
        Assert.Equal(code, resultGetApiStatus.StatusCode);
    }
    

    【讨论】:

    • 根据文档,它是在 2.2 中添加的,因此根据标题中指示的版本 OP 仍然有效。
    • IStatusCodeActionResult 是我要找的 :)
    【解决方案2】:

    测试逻辑存在缺陷,这也导致基于应用于被测对象的输入提供的结果好坏参半。

    根据允许在受试者中测试一条逻辑路径的预期行为测试特定结果。

    例如

    [Theory]
    [InlineData("wrong_token")]
    [InlineData("")]
    [InlineData(null)]
    public void Get_GetAnyAction_WithInvalidTokens_ReturnsUnauthorizedStatusCode(string token) {
        //Arrange
        int expected = StatusCodes.Status401Unauthorized;
    
        //Act
        StatusCodeResult result = _updatesController.GetApiStatus(token) as StatusCodeResult;
    
        //Assert
        int actual = result.StatusCode;
        Assert.Equal(expected, actual);
    }
    
    [Fact]
    public void Get_GetAnyAction_WithValidToken_ReturnsCorrectStatusCode() {
        //Arrange
        _vesselUpdatingMock.Setup(v => v.GetUpdatingStatus()).Returns(_sampleStatusModel);
        string token = "test_token";
    
        //Act
        OkObjectResult result = _updatesController.GetApiStatus(token) as OkObjectResult;
    
        //Assert
        int expected = StatusCodes.Status200OK;
        int actual = result.StatusCode;
        Assert.Equal(expected, actual);
    }
    

    这样你就避免了向测试添加条件逻辑,这意味着测试做了太多

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 2021-10-29
      • 2016-10-14
      相关资源
      最近更新 更多