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

如何用Xunit和Moq模拟Entity DbContext插入?遇空引用错误

解决Moq模拟DbContext时Set()空引用的问题

我来帮你搞定这个单元测试里的空引用问题!你遇到的错误核心原因很明确:你Mock出来的DbContext,它的Set<T>()方法没有被正确配置,调用时返回了null,所以当ARepository执行Context.Set<T>().Add(entity)时,自然就触发了空引用异常。

下面是一步步的修复方案,亲测有效:

1. 先Mock一个可用的DbSet

首先得给你的实体类(比如假设是YourEntity)创建一个Mock的DbSet<T>实例,这样后续DbContext才能返回它:

var mockDbSet = new Mock<DbSet<YourEntity>>();

2. 让Mock DbContext返回这个DbSet

接下来关键的一步:配置你的Mock DbContext,让它在调用Set<YourEntity>()时返回上面创建的mockDbSet,而不是默认的null:

var mockContext = new Mock<YourDbContext>();
// 重点:Setup Set<T>方法的返回值
mockContext.Setup(c => c.Set<YourEntity>()).Returns(mockDbSet.Object);

3. 编写完整的单元测试验证Add操作

现在把这个Mock的DbContext注入到你的ARepository里,执行Add方法后,就能验证是否正确调用了Add操作:

[Fact]
public void Add_WantToWork()
{
    // Arrange
    var mockDbSet = new Mock<DbSet<YourEntity>>();
    var mockContext = new Mock<YourDbContext>();
    mockContext.Setup(c => c.Set<YourEntity>()).Returns(mockDbSet.Object);
    
    var repository = new ARepository(mockContext.Object);
    var testEntity = new YourEntity { /* 这里设置你的测试实体属性 */ };

    // Act
    repository.Add(testEntity);

    // Assert
    // 验证DbSet的Add方法是否被精确调用了一次,参数就是我们的测试实体
    mockDbSet.Verify(d => d.Add(testEntity), Times.Once);
}

额外小技巧

  • 如果你的ARepository是泛型仓库,只需要把上面的YourEntity替换成泛型参数即可,适配所有实体类。
  • 要是你还需要验证SaveChanges()是否被调用,可以再加一段配置:
    // 配置SaveChanges返回1,表示保存成功
    mockContext.Setup(c => c.SaveChanges()).Returns(1);
    
    然后在Assert阶段验证:
    mockContext.Verify(c => c.SaveChanges(), Times.Once);
    

内容的提问来源于stack exchange,提问作者Kevin C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:58:32