1

构架

.NETCoreApp 1.1
EF Core 1.1.1
Xunit 2.2.0
Moq 4.7.8

Controller Post 方法
_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 时,您可以看到代码抛出错误(由中间件处理)

_yourRepository.Save() 方法

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

我不知道如何解决这个问题,我也不是 100% 确定它为什么会失败。

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

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

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

4

3 回答 3

2

您需要设置存储库以从异步方法返回正确的任务。起订量允许使用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);
}
于 2017-04-21T10:07:47.430 回答
1

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

显然,你不应该检查(断言)你不确定的东西(比如返回值)。

于 2017-04-21T10:05:09.817 回答
0

MockSave方法false默认返回。您需要明确设置true为返回值:

mockRepo.Setup(x => x.Save()).Returns(Task<bool>.FromResult(true));
于 2017-04-21T10:06:01.477 回答