c# - XUnit + Moq + FluentAssertions,在 Task 上检查 null 而不是正确的对象
问题描述
我是单元测试和起订量的新手。
使用 Postman 测试 DeleteItemAsync(),
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> DeleteItemAsync(string id)
{
var item = _ItemRepo.GetItemByIdAsync(id);
if (item == null)
return NotFound();
await _itemRepo.DeleteItemAsync(id);
return NoContent();
}
当找不到该项目时,我会得到正确的结果 NotFound。
运行我的单元测试时它失败了,因为在控制器中,它正在检查由 moq _repoStub 调用 GetItemByIdAsync(id) 返回的 Task 对象是否为空。
[Fact]
public async Task DeleteItemAsync_ItemDoesntExist_ReturnsNotFound()
{
// Arrange
_repoStub
.Setup(repo => repo.GetItemByIdAsync(It.IsAny<String>()))
.ReturnsAsync((Item)null);
_repoStub
.SetupSequence(repo => repo.DeleteItemAsync(It.IsAny<String>()))
.Returns(Task.FromResult<NotFoundResult>(null));
var controller = new ItemController(_repoStub.Object, _mapperStub);
// Act
var actionResult = await controller.DeleteItemAsync(It.IsAny<String>());
// Assert
actionResult.Should().BeOfType<NotFoundResult>();
}
解决方案
GetItemByIdAsync
应在待测对象中等待
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> DeleteItemAsync(string id)
{
var item = await _ItemRepo.GetItemByIdAsync(id); //<--!!!
if (item == null)
return NotFound();
await _itemRepo.DeleteItemAsync(id);
return NoContent();
}
否则它将返回 a Task
,因此不会null
如您的错误所示。
另外,请注意,它It.IsAny
应该只用在期望表达式中,而不是作为变量
[Fact]
public async Task DeleteItemAsync_ItemDoesntExist_ReturnsNotFound()
{
// Arrange
_repoStub
.Setup(repo => repo.GetItemByIdAsync(It.IsAny<String>()))
.ReturnsAsync((Item)null);
_repoStub
.SetupSequence(repo => repo.DeleteItemAsync(It.IsAny<String>()))
.Returns(Task.FromResult<NotFoundResult>(null));
var controller = new ItemController(_repoStub.Object, _mapperStub);
// Act
var actionResult = await controller.DeleteItemAsync(""); //<--It.IsAny<String>() removed
// Assert
actionResult.Should().BeOfType<NotFoundResult>();
}
推荐阅读
- sql - 尝试在 SQL Server 2005 上的两个数据库之间合并缺少的项目时出错
- hazelcast - 使用基于地图条目的 ttl 在 hazelcast 地图中批量加载
- c# - 使用 Xero.NetStandard.OAuth2.Api 将文件附加到 xero 发票
- python - 使用 PyTorch 计算函数的导数
- html - 单击行中的按钮时,在 tr 标记中触发不需要的功能
- time - 如何在一天中的特定时间运行 cypress 测试?
- javascript - 根据 object.differentValue === 静态值仅将 object.value 存储到 set() 中
- asp.net - 使用 Azure AD 保护 ASP.NET Core Web API
- c# - Xamarin Android Java 绑定库 .aar CS0102 类型“EventEventArgs”已包含“p0”的定义
- postgresql - PostgreSQL 中的枢轴总和