[英]Unit Test Save Changes failing
Frameworks 构架
.NETCoreApp 1.1
EF Core 1.1.1
Xunit 2.2.0
Moq 4.7.8
Controller Post Method 控制器发布方法
_yourRepository
is injected in the controllers constructor and is of type IYourRepository
_yourRepository
注入到controller构造函数中,类型为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();
}
Unit Test that fails 单元测试失败
[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);
}
The test fails because the line 测试失败是因为线路
if (!await _yourRespository.Save())
Always evaluates to true. 始终评估为true。 When it evaluates to true you can see that the code throws an error (which is handled by middleware)
当它的计算结果为true时,您可以看到代码抛出错误(由中间件处理)
_yourRepository.Save() method _yourRepository.Save()方法
public async Task<bool> Save()
{
return (await _yourContext.SaveChangesAsync() >= 0);
}
I'm not sure how to solve the problem and I'm not 100% sure why it is failing. 我不知道如何解决这个问题,我不能100%肯定它为什么会失败。
Is it because the mocked IYourRepository
interface doesn't include an implementation of the Save
method? 是因为
IYourRepository
接口不包含Save
方法的实现吗?
If so, does that mean to test the Post
method I would need to mock my DbContext and construct my YourRepository
object using it? 如果是这样,这是否意味着测试
Post
方法我需要模拟我的DbContext并使用它构造我的YourRepository
对象?
Any explanation as to why this is failing and how to rectify it would be much appreciated 关于为什么失败以及如何纠正它的任何解释将非常感激
You need to setup the repo to return a proper task from the async method. 您需要设置repo以从异步方法返回正确的任务。 Moq allows this using
ReturnsAsync
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);
}
Replace new Mock<IYourRepository>();
替换
new Mock<IYourRepository>();
with new Mock<IYourRepository>(MockBehavior.Strict);
使用
new Mock<IYourRepository>(MockBehavior.Strict);
- now it will throw exceptions when any method without Setup
is called. - 现在,当调用没有
Setup
任何方法时,它将抛出异常。
Obviously, you should not check (assert) something (like return values) you do not determined. 显然,你不应该检查(断言)你没有确定的东西(比如返回值)。
Mock Save
method returns false
by default. Mock
Save
方法默认返回false
。 You need to explicitly setup true
as return value: 您需要显式设置
true
作为返回值:
mockRepo.Setup(x => x.Save()).Returns(Task<bool>.FromResult(true));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.