什么测试足以对 MVC 中的 "Create" 控制器方法进行单元测试?
Whats tests would sufficiently Unit Test a "Create" controller method in MVC?
我想测试这个(控制器方法):
public async Task<IActionResult> Create(SecurityQuestionViewModel securityQuestion)
{
if (ModelState.IsValid)
{
SecurityQuestion dataModel = new SecurityQuestion();
dataModel.questionText = securityQuestion.QuestionText;
await _securityRepository.AddAsync(dataModel);
return RedirectToAction("Index");
}
else
{
return View();
}
}
我的单元测试(到目前为止)是这样的?
public async Task ModelContainsNewObjectAfterCreate()
{
//Arrange
_repository = new Mock<ISecurityQuestionRepository>();
_repository.Setup(repo => repo.GetAllAsync()).Returns(Task.FromResult(securityQuestion()));
_controller = new SecurityQuestionsController(_repository.Object, _mapper);
SecurityQuestion dataModel = new SecurityQuestion();
dataModel.questionText = "This is the new added question";
SecurityQuestionViewModel sqvm = new SecurityQuestionViewModel();
sqvm.QuestionText = dataModel.questionText;
//Act
var result = await _controller.Create(sqvm);
//Assert
var viewResult = Assert.IsType<RedirectToActionResult>(result);
_repository.Verify(r => r.AddAsync(dataModel), Times.Once);
}
viewResult
通过。
_repository
验证没有。
感觉我需要验证 AddAsync
方法 运行(将向现有存储库添加记录)。可能我的设置有误
感觉我还需要在 AddAsync
方法 运行 之后验证存储库中 "questions" 的数量。
我正在尝试了解什么构成充分的测试以及如何使用最小起订量模拟 "Add"。
如有任何见解,我们将不胜感激。
这个似乎接近我想要的。
您只能在操作中测试以下内容:
- 模型有效时的情况。
- 模型无效时的情况
只有两种情况。如果满足第一种情况,您可以验证 AddAsync()
是否使用类型为 SecurityQuestion
.
的任何参数执行
你可以这样模拟 AddAsync()
:
repository.Setup(r => r.AddAsync(It.IsAny<SecurityQuestion>())
.Returns(Task.FromResult(false));
并验证:
repository.Verify(r => r.AddAsync(It.IsAny<SecurityQuestion>()), Times.Once);
这就是你所能做到的!
您不能模拟 SecurityQuestion
模型,因为它使用 new
关键字,您尝试模拟的代码应该被删除。
这就是您需要做的全部,因为您的整个逻辑就是 if/else 语句。其他一切都会正常执行。只有另一件事可能会出现意外行为,如果 AddAsync()
抛出异常。
验证失败,因为模型是在被测方法中创建的,因此不匹配。您可以做的是将 It.Is
与与模型属性匹配的谓词一起使用
_repository.Verify(r => r.AddAsync(It.Is<SecurityQuestion>(m => m.questionText == dataModel.questionText)), Times.Once);
我想测试这个(控制器方法):
public async Task<IActionResult> Create(SecurityQuestionViewModel securityQuestion)
{
if (ModelState.IsValid)
{
SecurityQuestion dataModel = new SecurityQuestion();
dataModel.questionText = securityQuestion.QuestionText;
await _securityRepository.AddAsync(dataModel);
return RedirectToAction("Index");
}
else
{
return View();
}
}
我的单元测试(到目前为止)是这样的?
public async Task ModelContainsNewObjectAfterCreate()
{
//Arrange
_repository = new Mock<ISecurityQuestionRepository>();
_repository.Setup(repo => repo.GetAllAsync()).Returns(Task.FromResult(securityQuestion()));
_controller = new SecurityQuestionsController(_repository.Object, _mapper);
SecurityQuestion dataModel = new SecurityQuestion();
dataModel.questionText = "This is the new added question";
SecurityQuestionViewModel sqvm = new SecurityQuestionViewModel();
sqvm.QuestionText = dataModel.questionText;
//Act
var result = await _controller.Create(sqvm);
//Assert
var viewResult = Assert.IsType<RedirectToActionResult>(result);
_repository.Verify(r => r.AddAsync(dataModel), Times.Once);
}
viewResult
通过。
_repository
验证没有。
感觉我需要验证 AddAsync
方法 运行(将向现有存储库添加记录)。可能我的设置有误
感觉我还需要在 AddAsync
方法 运行 之后验证存储库中 "questions" 的数量。
我正在尝试了解什么构成充分的测试以及如何使用最小起订量模拟 "Add"。
如有任何见解,我们将不胜感激。
这个
您只能在操作中测试以下内容:
- 模型有效时的情况。
- 模型无效时的情况
只有两种情况。如果满足第一种情况,您可以验证 AddAsync()
是否使用类型为 SecurityQuestion
.
你可以这样模拟 AddAsync()
:
repository.Setup(r => r.AddAsync(It.IsAny<SecurityQuestion>())
.Returns(Task.FromResult(false));
并验证:
repository.Verify(r => r.AddAsync(It.IsAny<SecurityQuestion>()), Times.Once);
这就是你所能做到的!
您不能模拟 SecurityQuestion
模型,因为它使用 new
关键字,您尝试模拟的代码应该被删除。
这就是您需要做的全部,因为您的整个逻辑就是 if/else 语句。其他一切都会正常执行。只有另一件事可能会出现意外行为,如果 AddAsync()
抛出异常。
验证失败,因为模型是在被测方法中创建的,因此不匹配。您可以做的是将 It.Is
与与模型属性匹配的谓词一起使用
_repository.Verify(r => r.AddAsync(It.Is<SecurityQuestion>(m => m.questionText == dataModel.questionText)), Times.Once);