【问题标题】:Unit testing and mocking单元测试和模拟
【发布时间】:2021-03-01 19:46:20
【问题描述】:
我是 ASP.NET Core MVC 的新手,我想知道是否有人可以帮助我进行单元测试以从数据库中删除用户
控制器
public async Task<ActionResult> RemoveIdAsync(string Id)
{
try
{
var result = await _udService.RemoveId(Id);
return Ok(result);
}
catch (ServiceException)
{
return _internalServerErrorStatusCode;
}
}
【问题讨论】:
标签:
c#
unit-testing
asp.net-core
graphql
mocking
【解决方案1】:
测试应该返回asynt Task,因为被测对象也是异步的
使用 ReturnsAsync 将模拟成员设置为从异步调用返回
被测对象没有使用User 类,因此测试并不真正需要它
public async Task RemoveIdAsyncTest() {
//Arrange
_mockudService //...assuming Mock<IUdService>
.Setup(_ => _.RemoveId(It.IsAny<string>()))
.ReturnsAsync(true);
var removeController = new RemoveController(_mockudService.Object);
var id = "...";
//Act
var result = await removeController.RemoveIdAsync(id); //will return OkObjectResult
//Assert
OkObjectResult actual = result as OkObjectResult;
Assert.IsNotNull(actual);
Assert.IsTrue((bool)actual.Value);
// ... assert expected behavior
}
【解决方案2】:
很高兴看到您开始编写单元测试。
上一个答案中提供了一个示例,因此我不会重复,但我会强调更多地了解单元测试。
单元测试
验证整个系统一小部分行为的测试。
使测试成为单元测试的原因在于,被测系统 (SUT) 是整个系统的一个非常小的子集,并且对于不参与构建软件的人来说可能是无法识别的。实际的 SUT 可能小到作为一个或多个设计决策的结果的单个对象或方法,尽管它的行为也可以追溯到功能需求的某些方面。客户或业务领域专家不需要单元测试可读、可识别或可验证。
如果满足以下条件,则测试不是单元测试:
It talks to the database.
It communicates across the network.
It touches the file system.
It can’t run correctly at the same time as any of your other unit tests.
You have to do special things to your environment (such as editing config files) to run it.
单元测试鼓励良好的设计和快速的反馈,它们似乎可以帮助团队避免很多麻烦。
更多信息:https://codeanit.medium.com/developers-guide-write-good-test-5e3e3cdec78e
此外,当我们使用 MVC 框架时,MVC 中的经验法则是Slim Controller, Fat Model。话虽如此,您可以将存储库模型用于您的数据库活动,并将您的业务逻辑移动到单独的类中。
清洁代码、SOLID 设计原则和遵循清洁架构也将具有一定的价值。 https://blog.ndepend.com/clean-architecture-example-part-one
祝你一切顺利!
干杯,