单元测试保存更改失败
Unit Test Save Changes failing
框架
.NETCoreApp 1.1
EF Core 1.1.1
Xunit 2.2.0
Moq 4.7.8
控制器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
对象?
如果能解释为什么失败以及如何纠正它,我们将不胜感激
将 new Mock<IYourRepository>();
替换为 new Mock<IYourRepository>(MockBehavior.Strict);
- 现在调用任何不带 Setup
的方法时都会抛出异常。
显然,你不应该检查(断言)你不确定的东西(比如 return 值)。
Mock Save
方法 returns false
默认。您需要将 true
显式设置为 return 值:
mockRepo.Setup(x => x.Save()).Returns(Task<bool>.FromResult(true));
您需要将存储库设置为 return 来自异步方法的适当任务。 Moq 允许使用 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);
}
框架
.NETCoreApp 1.1
EF Core 1.1.1
Xunit 2.2.0
Moq 4.7.8
控制器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
对象?
如果能解释为什么失败以及如何纠正它,我们将不胜感激
将 new Mock<IYourRepository>();
替换为 new Mock<IYourRepository>(MockBehavior.Strict);
- 现在调用任何不带 Setup
的方法时都会抛出异常。
显然,你不应该检查(断言)你不确定的东西(比如 return 值)。
Mock Save
方法 returns false
默认。您需要将 true
显式设置为 return 值:
mockRepo.Setup(x => x.Save()).Returns(Task<bool>.FromResult(true));
您需要将存储库设置为 return 来自异步方法的适当任务。 Moq 允许使用 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);
}