Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NETWebAPI控制器单元测试岗_Asp.net Mvc_Unit Testing_Moq_Xunit - Fatal编程技术网

Asp.net mvc ASP.NETWebAPI控制器单元测试岗

Asp.net mvc ASP.NETWebAPI控制器单元测试岗,asp.net-mvc,unit-testing,moq,xunit,Asp.net Mvc,Unit Testing,Moq,Xunit,我不熟悉单元测试,正在尝试为我的Web API控制器的POST方法创建一些Xunit测试 以下是我的控制器的POST方法: [HttpPost("")] public async Task<IActionResult> CreateArea([FromBody] AreaForCreationDto area) { // Check that the 'area' object parameter can be de-serialised to a AreaForCreati

我不熟悉单元测试,正在尝试为我的Web API控制器的
POST
方法创建一些Xunit测试

以下是我的控制器的
POST
方法:

[HttpPost("")]
public async Task<IActionResult> CreateArea([FromBody] AreaForCreationDto area)
{
    // Check that the 'area' object parameter can be de-serialised to a AreaForCreationDto.
    if (area == null)
    {
        var message = "Could not de-serialise the request body to an AreaForCreationDto object";
        _logger.LogError(message);

        // Return an error 400.
        return BadRequest(message);
    }

    /*
     * ModelState.IsValid is determined by the attributes associated with the 
     * Data Annotations on the properties of the ViewModel.
     */
    if (!ModelState.IsValid)
    {
        // Return a response with a Status Code 422.
        return new UnprocessableEntityObjectResult(ModelState);
    };

    // Map a AreaForCreationDto object to a Area entity.
    var areaEntityToAdd = _mapper.Map<Area>(area);

    // Call the repository to add the new Area entity to the DbContext.
    _areaRepository.AddArea(areaEntityToAdd);

    // Save the new Area entity, added to the DbContext, to the SQL database.
    if (await _areaRepository.SaveChangesAsync())
    {
        // Note: AutoMapper maps the values of the properties from the areaEntityToAdd
        // to a new areaToReturn object.
        // This ensures that we don't expose our Area entity to the web browser.
        var areaToReturn = _mapper.Map<AreaDto>(areaEntityToAdd);

        // Return a 201 'created' response along with the location URL in the
        // response Header.
        return CreatedAtRoute("GetArea",
            new { id = areaToReturn.Id },
            areaToReturn);
    }
    else {
        // The save failed.
        var message = $"Could not save new Area {areaEntityToAdd.Id} to the database.";
        _logger.LogWarning(message);
        throw new Exception(message);
    };
}
当单元测试尝试断言.IsType(result)时,我遇到了一个异常。调试显示控制器未能保存到存储库。我的
AreaRepository
具有以下AddArea函数,该函数不返回值,因此我假设我的
\u mockAreaRepository
不需要设置
返回
条件(此处可能错误)


我是否需要为调用
savechangesync()
的结果配置我的
mockAreasRepository

是,因为它是异步的。您需要模拟已完成任务的返回以允许该方法

await _areaRepository.SaveChangesAsync()
能够继续

您还需要通过返回
任务
并等待测试中的方法,将测试更新为异步测试

[Fact]
public async Task ReturnAreaForCreateArea() { //<-- note test is now async as well
    //Arrange

    var _mockAreaRepository = new Mock<IAreaRepository>();
    _mockAreaRepository
        .Setup(x => x.AddArea(testArea));

    _mockAreaRepository
        .Setup(x => x.SaveChangesAsync())
        .ReturnsAsync(true); //<-- returns completed Task<bool> when invoked

    var _mockMapper = new Mock<IMapper>();
    _mockMapper
        .Setup(_ => _.Map<Area>(It.IsAny<AreaForCreationDto>()))
        .Returns(testArea);
    _mockMapper
        .Setup(_ => _.Map<AreaDto>(It.IsAny<Area>()))
        .Returns(testAreaDto);

    var _mockLogger = new Mock<ILogger<AreasController>>();
    var _sut = new AreasController(_mockAreaRepository.Object, _mockLogger.Object, _mockMapper.Object);

    // Act
    var result = await _sut.CreateArea(testAreaForCreationDto);//<-- await 

    // Assert
    Assert.NotNull(result);
    var objectResult = Assert.IsType<CreatedAtRouteResult>(result);
    var model = Assert.IsAssignableFrom<AreaDto>(objectResult.Value);
    var areaDescription = model.Description;
    Assert.Equal("Test Area For Creation", areaDescription);
}
[事实]
公共异步任务ReturnAreaForCreateArea(){//x.AddArea(testArea));
_模拟区域存储库
.Setup(x=>x.saveChangesSync())
.ReturnsAsync(true);//wk.Map(It.IsAny())
.回报(testArea);
_模拟制图器
.Setup(=>u.Map(It.IsAny()))
.归还(遗嘱);
varu mockLogger=new Mock();
var _sut=新的区域控制器(_mockAreaRepository.Object、_mockLogger.Object、_mockMapper.Object);
//表演

var结果=等待_sut.CreateArea(TestAreaForCreationTo);//是的,因为它是异步的。您需要模拟已完成任务的返回,以允许该方法继续。您还需要通过返回
任务
将测试更新为异步,并在testLong delay下等待该方法,因为我被转移到另一个项目。我们最终尝试了您非常有用的建议,但第一次尝试rtion(.NotNull)失败。控制器将新创建的
区域
实体保存到存储库中,然后返回一个
区域
,该区域是通过调用
GetArea
路径上的函数创建的,传递新的
Id
。我需要配置控制器的
GetArea
函数才能工作吗?然后是这样的您的代码中的mething与原来显示的有所不同。代码中的逻辑不允许返回null。如果
SaveChangesAsync()
成功,如果失败,我们没有提供返回
错误代码500
,因此我们不应该返回
null
。我将继续尝试,看看在保存过程中出现了什么问题。如果我的
等待_areaRepository.saveChangesSync()
返回
true
,然后我的被测控制器将
AreaEntityToAdd
映射到
AreaDTO
,并将其与新的
Area
id一起传递到控制器的
GetArea
方法。我还没有说明我的系统中
GetArea
函数中的映射和存储库操作
\u mockMapper
\u mockRepository
。我需要吗?是的,用于映射
[Fact]
public async Task ReturnAreaForCreateArea() { //<-- note test is now async as well
    //Arrange

    var _mockAreaRepository = new Mock<IAreaRepository>();
    _mockAreaRepository
        .Setup(x => x.AddArea(testArea));

    _mockAreaRepository
        .Setup(x => x.SaveChangesAsync())
        .ReturnsAsync(true); //<-- returns completed Task<bool> when invoked

    var _mockMapper = new Mock<IMapper>();
    _mockMapper
        .Setup(_ => _.Map<Area>(It.IsAny<AreaForCreationDto>()))
        .Returns(testArea);
    _mockMapper
        .Setup(_ => _.Map<AreaDto>(It.IsAny<Area>()))
        .Returns(testAreaDto);

    var _mockLogger = new Mock<ILogger<AreasController>>();
    var _sut = new AreasController(_mockAreaRepository.Object, _mockLogger.Object, _mockMapper.Object);

    // Act
    var result = await _sut.CreateArea(testAreaForCreationDto);//<-- await 

    // Assert
    Assert.NotNull(result);
    var objectResult = Assert.IsType<CreatedAtRouteResult>(result);
    var model = Assert.IsAssignableFrom<AreaDto>(objectResult.Value);
    var areaDescription = model.Description;
    Assert.Equal("Test Area For Creation", areaDescription);
}