微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试控制器 post 方法时如何模拟 MySql 数据库返回的主键

如何解决测试控制器 post 方法时如何模拟 MySql 数据库返回的主键

我的 xunit 测试失败,因为在单元测试时数据库没有更新预期的 Id。 如何模拟数据库创建的 id/主键?

[HttpPost]
public async Task<ActionResult<AccountReadDto>> CreateAccountAsync(AccountCreateDto createAccountDto)
{
    var account = _mapper.Map<Account>(createAccountDto); // Id is int equal to 0
    await _accountRepo.CreateAccountAsync(account); // repo calls db and updates Id with pk
    _accountRepo.SaveChanges();

    var accountReadDto = _mapper.Map<AccountReadDto>(account);
    return CreatedAtRoute(nameof(GetAccountByIdAsync),new { AccountId = accountReadDto.AccountId },accountReadDto);
}

[Fact]
public async Task CreateAccountAsync_NewAccount_ReturnsAccountReadDto()
{
    var expectedAccount = CreaterandomAccount(); // has id
    var createDto = _mapperStub.Map<AccountCreateDto>(expectedAccount); // doesn't have id

    _repoStub
        .Setup(repo => repo.CreateAccountAsync(expectedAccount))
        .Returns(Task.CompletedTask);
    var controller = new AccountController(_repoStub.Object,_mapperStub);

    var actionResult = await controller.CreateAccountAsync(createDto);

    var result = (actionResult.Result as CreatedAtRouteResult).Value as AccountReadDto;
    result.Should().BeEquivalentTo(
        expectedAccount,options => options.ComparingByMembers<AccountReadDto>().ExcludingMissingMembers() // excluding login info
    );
}

解决方法

此代码不正确:

_repoStub
    .Setup(repo => repo.CreateAccountAsync(expectedAccount))

设置 CreateAccountAsync 只是为了将 expectedAccount 实例作为参数传递的情况。 (映射后就不一样了)。使用 It.IsAny<T>() 配置方法以使用任何参数。然后使用 Callback<T>(Action<T>) 访问传递给模拟调用的参数:

_repoStub
    .Setup(repo => repo.CreateAccountAsync(It.IsAny<Account>()))
    .Callback<Account>(a => a.Id = expectedAccount.Id)
    .Returns(Task.CompletedTask);

在该代码中,您将 CreateAccountAsync 方法配置为返回 Task.CompletedTask 并将传入参数 id 修改为 expectedAccount.Id

Returns(Task.CompletedTask) 可以省略。 (这是默认行为)

关于 Callback<T> 的其他信息:link

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?