我正在开发 .NET Core 6.0 Web API。 我有一个
DeleteComment
方法,并且我为其编写了一个测试方法,如下所示:
[Fact]
public void DeleteComment_WithValidId_ReturnsNoContentResult()
{
var commentId = 1;
var result = _controller.DeleteComment(commentId);
Assert.IsType<NoContentResult>(result);
_mockCommentService.Verify(service => service.DeleteComment(commentId), Times.Once);
}
// 删除:api/Comments/5
[HttpDelete("{id}")]
public IActionResult DeleteComment(int id)
{
var deletingComment = _commentService.GetComment(id);
if (deletingComment == null)
{
return NotFound();
}
_commentService.DeleteComment(id);
return NoContent();
}
通过 ID 获取评论:
public Comment GetComment(int id)
{
return _comments.FirstOrDefault(comment => comment.Id == id);
}
删除评论:
public void DeleteComment(int id)
{
var commentToDelete = _comments.FirstOrDefault(comment => comment.Id == id);
if (commentToDelete != null)
{
_comments.Remove(commentToDelete);
}
}
虽然它应该返回
NoContentResult
,但它却意外地返回 NotFoundResult
。我使用 Postman 和断点使用相同的 commentId 测试了 API,它工作正常。我的代码有错误吗?
这是运行
DeleteComment_WithValidId_ReturnsNoContentResult()
测试的结果
Assert.IsType() Failure
Expected: Microsoft.AspNetCore.Mvc.NoContentResult
Actual: Microsoft.AspNetCore.Mvc.NotFoundResult
您的测试用例运行正常。首先,当您将函数作为一个单元进行测试时。您不应该允许您的测试用例依赖于外部依赖项。当我们编写单元测试用例时,我们相信系统的其他部分正在按预期工作,并且我们只测试代码单元。因此,首先修复这个测试用例,我们必须模仿测试用例中依赖项的行为。以下是您可以执行此操作的方法。
对于我们来说,这里的单位是
DeleteComment
方法,它取决于 _commonService
,即 ICommonService
希望如此。如果它是一个类,并且像 GetComment
这样的方法不是虚拟的,我们将无法模拟它。
Mocking 意味着模仿对象的行为。这里将使用
Moq
lib。我猜你已经在使用它了。只是我们需要配置它。
[Fact]
public void DeleteComment_WithValidId_ReturnsNoContentResult()
{
var commentId = 1;
var comment = new Comment(){
Id = 1,
};
// setup behaviour
_mockCommentService.Setup(x=>x.GetComment(commentId)).Returns(comment);
var controller = new DeleteController(_mockCommonService.Object);
var result = controller.DeleteComment(commentId);
Assert.IsType<NoContentResult>(result);
_mockCommentService.Verify(service => service.DeleteComment(commentId), Times.Once);
}