问题描述
我想测试Web api 2 post方法,如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public IHttpActionResult CreateEquipment(EquipmentDto equipmentDto)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var equipment = Mapper.Map<EquipmentDto,Equipment>(equipmentDto);
unitOfWork.Equipment.Add(equipment);
unitOfWork.Complete();
equipmentDto.Id = equipment.Id;
return Created(new Uri(Request.RequestUri + "/" + equipment.Id),equipmentDto);
}
我正在使用Moq和NUnit进行测试。我的SetUp方法和测试方法如下:
[SetUp]
public void SetUp()
{
unitOfWork = new Mock<IUnitOfWork>();
controller = new EquipmentController(unitOfWork.Object);
Mapper.Initialize(c => c.AddProfile<MappingProfile>());
}
[Test]
public void CreateEquipment_ModelIsValid_ReturnCreated()
{
var equipmentDto = new EquipmentDto();
var equipment = Mapper.Map<EquipmentDto,Equipment>(equipmentDto);
unitOfWork.Setup(uow => uow.Equipment.Add(equipment));
unitOfWork.Setup(uow => uow.Complete());
var result = controller.CreateEquipment(equipmentDto) as CreatedAtRouteNegotiatedContentResult<EquipmentDto>;
Assert.IsNotNull(result);
}
我在控制器行中收到NullReferenceException:
return Created(new Uri(Request.RequestUri + "/" + equipment.Id),equipmentDto);
equipment.Id和equipmentDto不为null。 null为Request,这就是Request.RequestUri引发异常的原因。
如何正确设置请求以避免异常并通过测试?我将不胜感激。
我知道有一个类似的问题:ASP.NET Testing Api controller: Uri(Request.GetEncodedUrl()...) returns null 但这与ASP.NET Core有关,我无法找到如何解决ASP.NET MVC中的问题。
var context = new Mock<HttpContextBase>();
context.Setup(x => x.Request.Url).Returns(new Uri("/Equipment/New",UriKind.Relative));
但这没有帮助。
解决方法
您需要使用HttpRequestMessage
配置控制器,例如:
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://localhost:5000/Equipment/New",UriKind.Absolute)
};
var controllerContext = new HttpControllerContext
{
Request = request
};
var controller = new EquipmentController(unitOfWork.Object)
{
ControllerContext = controllerContext
};
...
var result = controller.CreateEquipment(equipmentDto) as CreatedNegotiatedContentResult<EquipmentDto>;
Assert.NotNull(result);
还要注意,您从端点返回CreatedNegotiatedContentResult
,但没有返回CreatedAtRouteNegotiatedContentResult