c# - EF Entry.State 上的单元测试失败

标签 c# entity-framework unit-testing

是否可以对此进行单元测试?

public class MyRepository<T> where T : IdentityUser, new()
{
   public async Task UpdateAsync(T user)
    {
        _context.Entry(user).State = EntityState.Modified;
        _context.Entry(user).Property("UserName").IsModified = false;
        await _context.SaveChangesAsync();
    }
}

[TestInitialize] 将 1 个用户添加到存储库

_user = new IdentityUser { Id = "70a038cdde40" };

IDbSet<IdentityUser> users = new FakeDbSet<IdentityUser> { _user };

var dbContext = new Mock<MyDbContext<IdentityUser>>();
dbContext.Setup(x => x.Users).Returns(() => users);

_repository = new MyRepository<IdentityUser>(dbContext.Object);

我正在尝试用这个进行测试

private MyRepository<IdentityUser> _repository;

[TestMethod]
public async Task UpdateUser_Success2()
{
    var user = await _repository.FindByIdAsync("70a038cdde40");
    Assert.IsFalse(user.EmailConfirmed, "User.EmailConfirmed is True");

    user.EmailConfirmed = true;

    await _repository.UpdateAsync(user);

    (...)
}

但它死于 UpdateAsync 的第一行。是错误的测试还是 UpdateAsync 实现?有什么办法可以测试吗?

编辑

我按照 Belogix 的建议添加了

 dbContext.Setup(x => x.Entry(It.IsAny<IdentityUser>()))
                       .Returns(() => dbContext.Object.Entry(_user));

我想这让我更接近了,但仍然有非虚拟错误:非虚拟成员上的设置无效:x => x.Entry(It.IsAny())

最佳答案

有史以来最好的引述:“计算机科学中的所有问题都可以通过另一个间接级别来解决”- Butler Lampson。

看起来如果不添加一些额外的抽象就无法直接测试。我不得不以这种方式重构我的 UpdateAsync 方法

public async Task UpdateAsync(T user)
{
    SetEntityStateModified(user);
    SetPropertyIsModified(user);
    await _context.SaveChangesAsync();
}

public virtual void SetPropertyIsModified(T user)
{
    _context.Entry(user).Property("UserName").IsModified = false;
}

public virtual void SetEntityStateModified(T user)
{
    _context.Entry(user).State = EntityState.Modified;
}

然后在初始化中更新我的测试代码

_repository = new Mock<MyRepository<IdentityUser>>(dbContext.Object);
_repository.Setup(x => x.SetEntityStateModified(It.IsAny<IdentityUser>()));
_repository.Setup(x => x.SetPropertyIsModified(It.IsAny<IdentityUser>()));

然后我的测试终于通过了

[TestMethod]
public async Task can_update_user_details()
{
    //Arrange
    var user = await _repository.Object.FindByIdAsync("70a038cdde40");
    Assert.IsFalse(user.EmailConfirmed, "User.EmailConfirmed is True");

    //Act            
    user.EmailConfirmed = true;

    await _repository.Object.UpdateAsync(user);
    var newUser = await _repository.Object.FindByIdAsync("70a038cdde40");

    //Assert
    Assert.IsTrue(newUser.EmailConfirmed, "User.EmailConfirmed is False");
}

关于c# - EF Entry.State 上的单元测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25768459/

相关文章:

c# - 使用httprequest下载文件

c# - 单元测试 EF DbUpdateConcurrencyException 处理

c# - 如何使用 LibGit2Sharp 部分暂存文件?

c# - WPF C# - MainWindows.g.cs 中的 "Unable to find namespace"错误

c# - 使用 EntityFramework 和 MVC ModelBinding 保存具有特殊字符的字段时出错

c# - EF Core 中 .Configuration.ProxyCreationEnabled 的等价物是什么?

android - 以编程方式启用 android 设备管理

unit-testing - 私有(private)/ protected 方法是否应该进行单元测试?

c# - 使用 Linq 过滤 ComboBox.DataSource?

c# - 与 Entity Framework 和 MySQL 的乐观并发