You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Entity Framework Core模拟DbSet.Add()方法?

EF Core模拟DbContext时Add方法不生效的解决办法

你当前用ReturnsDbSet模拟的DbSet仅提供查询数据的能力,不会自动处理Add这类修改操作,因此需要手动模拟Add方法,同时解决返回EntityEntry<Book>的问题,以下是两种简单可行的方案:

方案一:用Moq直接模拟Add方法并返回Mock的EntityEntry

无需直接实例化EntityEntry<Book>,用Moq创建它的模拟对象即可:

Mock<MyDbContext> fakeDbContext = new Mock<MyDbContext>();
List<Book> availableBooks = new List<Book>(); // 已在别处填充数据

// 创建EntityEntry的模拟对象
var mockEntityEntry = new Mock<EntityEntry<Book>>();

// 模拟BookRepository的Add方法:执行添加到集合,同时返回模拟的EntityEntry
fakeDbContext.Setup(ct => ct.BookRepository.Add(It.IsAny<Book>()))
    .Callback<Book>(newBook => availableBooks.Add(newBook))
    .Returns(mockEntityEntry.Object);

// 保留原有的ReturnsDbSet设置,确保查询能正常获取数据
fakeDbContext.Setup(ct => ct.BookRepository).ReturnsDbSet(availableBooks);

调用fakeDbContext.BookRepository.Add(newBook)时,newBook会被加入availableBooks集合,同时返回符合要求的EntityEntry<Book>对象。

方案二:自定义模拟DbSet类

如果需要模拟更多DbSet操作(比如Remove、Update),可以自行实现继承DbSet<T>的类,直接操作内存集合:

public class InMemoryDbSet<T> : DbSet<T> where T : class
{
    private readonly List<T> _innerList;

    public InMemoryDbSet(List<T> innerList)
    {
        _innerList = innerList;
    }

    // 重写Add方法,添加到内存集合并返回实体
    public override T Add(T entity)
    {
        _innerList.Add(entity);
        return entity;
    }

    // 支持返回EntityEntry的Add扩展方法
    public new EntityEntry<T> Add(T entity)
    {
        _innerList.Add(entity);
        return new Mock<EntityEntry<T>>().Object;
    }

    // 按需重写查询方法,确保查询行为符合预期
    public override List<T> ToList()
    {
        return _innerList.ToList();
    }
}

使用时替换原有的ReturnsDbSet:

fakeDbContext.Setup(ct => ct.BookRepository)
    .Returns(new InMemoryDbSet<Book>(availableBooks));

关键说明

ReturnsDbSet仅为DbSet提供查询数据源,不会自动将增删改操作绑定到内存集合,必须手动模拟这些方法的行为,才能让修改操作同步到availableBooks列表中。

内容的提问来源于stack exchange,提问作者Jean-David Lanz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:05:01