什么测试足以对 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"。

如有任何见解,我们将不胜感激。

这个似乎接近我想要的。

您只能在操作中测试以下内容:

  1. 模型有效时的情况。
  2. 模型无效时的情况

只有两种情况。如果满足第一种情况,您可以验证 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);