【发布时间】:2021-01-24 10:50:36
【问题描述】:
所以我对编写测试非常陌生。我创建了一个 ASP.NET 核心 web api 以及 angular。我必须为 Web API 控制器编写单元测试。我一直在阅读有关如何开始对 ASP.NET Web API 进行单元测试的 Microsoft 文档。但是我仍然非常不确定如何编写适当的测试。
我的控制器代码
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class OrdersController : ControllerBase
{
private readonly IOrderRepository _repo;
private readonly IMapper _mapper;
public OrdersController(IOrderRepository repo, IMapper mapper)
{
_repo = repo;
_mapper = mapper;
}
[AllowAnonymous]
[HttpPost()]
public async Task<IActionResult> AddOrder(OrderForMappingDto orderForMappingDto)
{
//if(orderForMappingDto.ARentalOrNot == null)
//{
// throw new Exception("Value can't be left null");
//}
var orderToCreate = _mapper.Map<TblOrder>(orderForMappingDto);
var createdOrder = await _repo.AddOrder(orderToCreate);
return Ok(createdOrder);
}
}
我的仓库代码
public class OrderRepository : IOrderRepository
{
private readonly MovieRentalDBContext _context;
public OrderRepository(MovieRentalDBContext context)
{
_context = context;
}
public async Task<TblOrder> AddOrder(TblOrder tblOrder)
{
await _context.TblOrder.AddAsync(tblOrder);
await _context.SaveChangesAsync();
return tblOrder;
}
}
我知道有很多嘲笑要做。但是我是否也需要模拟实体框架? 我写了一个简单的测试文件。
public void PostsAorder_WhenCalled_ReturnsOkWithResponse()
{
var mockOrderRepository = new Mock<IOrderRepository>();
var mockOrderMapper = new Mock<IMapper>();
var orderControllerObject = new OrdersController(mockOrderRepository.Object, mockOrderMapper.Object);
Task<IActionResult> contentResult = orderControllerObject.AddOrder(new OrderForMappingDto
{
ACustomerId = 3,
AMovieId = 18,
ARentalOrNot = false,
AOrderedDate = DateTime.Now
}) ;
//var contentResult = actionResult as OkNegotiatedContentResult<OrderForMappingDto>;
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Result);
}
OkNegotioatedContent 函数不适用于任务。我该如何使用它来完成任务。此外,即使在 DTO 中它们被归类为 [Required] 时,即使我没有提供最后 3 个参数,测试也会通过。有人可以帮助如何正确修改测试。
映射器配置-
【问题讨论】:
-
您不需要模拟整个实体框架。 IMO 您可以使用现有的开发数据库并在测试运行完成后删除在测试期间创建的所有对象。但是,如果您不想这样做,您可以使用 in memory database 中的 EF 核心,它完全存在于内存中,并且所有内容都会在事后被删除
-
另外,IMO,你也不需要模拟你的 repo 和 mapper,使用真实的东西。知道您的控制器方法是否适用于模拟数据对您有什么好处?您真正想知道的是您的控制器方法是否适用于真实数据
-
@MindSwipe 如果我使用真实的东西,那不就是将它们作为外部依赖的集成测试吗?
-
嗯,它使测试(同样,IMO)更有价值。现在你唯一的测试是你的控制器不返回空值,而不是如果实际上做了它应该做的事情(应用验证、映射和保存)。老实说,我从不关心单元测试的分类,只是确保我编写的所有代码都经过适当测试,这意味着至少有一个正面测试和一个负面测试,它们都涵盖了我能想到的所有边缘情况
标签: c# asp.net unit-testing mocking asp.net-core-webapi