【问题标题】:ASP.NET MVC unit testing WEB API Post method: Request.RequestUri throws an exceptionASP.NET MVC单元测试WEB API Post方法:Request.RequestUri抛出异常
【发布时间】:2020-11-10 22:25:47
【问题描述】:

我想测试 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 是 Request,这就是 Request.RequestUri 抛出异常的原因。

如何正确设置Request以避免异常并通过测试?我将不胜感激。

我知道有一个类似的问题: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));

但这并没有帮助。

【问题讨论】:

    标签: c# asp.net asp.net-mvc unit-testing


    【解决方案1】:

    您需要使用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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-16
      • 2013-01-02
      • 2013-10-10
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      相关资源
      最近更新 更多