如何测试返回 Ok(object) 的 ASP.NET Core 2.2 Web API GET IActionResult?
Posted
技术标签:
【中文标题】如何测试返回 Ok(object) 的 ASP.NET Core 2.2 Web API GET IActionResult?【英文标题】:How to test my ASP.NET Core 2.2 Web API GET IActionResult that returns Ok(object)? 【发布时间】: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);
IActionResult
的 StatusCode
属性是 200,但只有 DeclaredType
的属性是 null。
当断言时,最后我有我的resultGetApiStatus
null。
我没有找到类似的例子。如何正确投影result
?
重要编辑:
我发现只有this approach,这不能解决我的问题,关于各种情况[Theory]
,并不是我所有的其他操作都返回ObjectResult
,其中一些只返回StatusCode
。有和没有ObjectResult
的操作是否有任何通用方法?还是应该使用不同的测试?
【问题讨论】:
【参考方案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);
这样你就避免了向测试添加条件逻辑,这意味着测试做了太多
【讨论】:
以上是关于如何测试返回 Ok(object) 的 ASP.NET Core 2.2 Web API GET IActionResult?的主要内容,如果未能解决你的问题,请参考以下文章