单位测试保存更改失败



Frameworks

.NETCoreApp 1.1
EF Core 1.1.1
Xunit 2.2.0
Moq 4.7.8

控制器帖子方法
_yourRepository注入控制器构造函数,为IYourRepository

类型
[HttpPost(Name = "CreateMethod")]
public async Task<IActionResult> CreateMethod([FromBody] ObjectForCreationDto objectDto)
{
    if (objectDto== null)
    {
        return BadRequest();
    }
    if (!ModelState.IsValid)
    {
        return BadRequest();
    }
    await _yourRespository.CreateObject(objectDto);
    if (!await _yourRespository.Save())
    {
        throw new Exception("Creating this object failed on save.");
    }            
    return Ok();
}

失败的单元测试

[Fact]
public async Task CreateObject_WhenGoodDtoReceived_SuccessStatusReturned()
{
    // Arrange
    var mockRepo = new Mock<IYourRepository>();
    var controller = new YourController(mockRepo.Object);
    var objectForCreationDto = new ObjectForCreationDto { Code = "0001", Name = "Object One" };
    // Act
    var result = await controller.CreateObject(objectForCreationDto);
    // Assert
    Assert.IsType<OkObjectResult>(result);
}

测试失败,因为该行

if (!await _yourRespository.Save())

始终评估为true。当它评估为true时,您可以看到代码会引发错误(由中间件处理(

_yourrepository.save((方法

public async Task<bool> Save()
{
    return (await _yourContext.SaveChangesAsync() >= 0);
}

我不确定如何解决问题,我不确定100%确定为什么会失败。

是因为模拟的IYourRepository接口不包括Save方法的实现吗?

如果是这样,这是否意味着要测试Post方法,我需要模拟我的dbcontext并使用它构造我的YourRepository对象?

关于为什么失败以及如何纠正的任何解释,将不胜感激

您需要设置存储库以从异步方法返回适当的任务。司令允许使用ReturnsAsync

[Fact]
public async Task CreateObject_WhenGoodDtoReceived_SuccessStatusReturned()
{
    // Arrange
    var mockRepo = new Mock<IYourRepository>();
    mockRepo.Setup(_ => _.Save()).ReturnsAsync(true);//<-- ADD THIS
    var controller = new YourController(mockRepo.Object);
    var objectForCreationDto = new ObjectForCreationDto { Code = "0001", Name = "Object One" };
    // Act
    var result = await controller.CreateObject(objectForCreationDto);
    // Assert
    Assert.IsType<OkObjectResult>(result);
}

new Mock<IYourRepository>(MockBehavior.Strict);替换 new Mock<IYourRepository>();-现在它将在调用任何Setup的任何方法时都会抛出异常。

显然,您不应该检查(断言(您未确定的东西(例如返回值(。

模拟Save方法默认情况下返回false。您需要明确设置true作为返回值:

mockRepo.Setup(x => x.Save()).Returns(Task<bool>.FromResult(true));