【问题标题】:UnitTesing with Autofac, Moq - Getting Value cannot be null exception使用 Autofac、Moq 进行 UnitTesing - 获取值不能为空异常
【发布时间】:2020-03-16 14:10:23
【问题描述】:

我正在使用 EF6。生成的代码类似于:

public partial class MyDataContext : DbContext,IMyDataContext 
{
    public MyDataContext() : base("name=mydata")
    {
    }

    public virtual DbSet<getProjectsDraft> getProjectsDrafts { get; set; }
}

dbcontext 接口如下所示

public interface IxmcmcDbContext: IDisposable
{
   DbSet<getProjectsDraft> getProjectsDrafts { get; set; }
}

我正在为 DI 使用 Autofac,注册是在我的 global.asax.cs 中完成的,如下所示

//Entity Registering
builder.RegisterType<MyDataContext>().As<IMyDataContext>();

我所有的 DI 工作正常,但是当我使用 xUnity 实施单元测试时,我遇到了错误

基本测试代码:

public class BaseTest
    {
        public static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
        {
            var elementsAsQueryable = elements.AsQueryable();
            var dbSetMock = new Mock<DbSet<T>>();
            dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());
            return dbSetMock;
        }
    }

和项目测试

public class Projects_Test : BaseTest
    {
        [Fact]
        public void GetDraftProjectsList()
        {
            // Arrange
            var fixture = new Fixture();
            var draftProjects = new List<getProjectsDraft>
             {
                fixture.Create<getProjectsDraft>()
             };
            var draftMock = CreateDbSetMock(draftProjects);
            var myDataContextMock= new Mock<IMyDataContext>();
            myDataContextMock.Setup(x => x.getProjectsDrafts).Returns(draftMock.Object);
            var projectService = new ProjectRepo(mediciContextMock.Object);

            // Act
            var draftproject = projectService.GetDraftProjects(true, "test-02", "Test");

            // Assert
            Assert.NotNull(draftproject);
        }
    }

但是,我在 //Act draftproject 上收到 "Value cannot be null.\r\nParameter name: source" 错误。

我做错了什么?

【问题讨论】:

  • 试试myDataContextMock.SetupGet(x =&gt; x.getProjectsDrafts).Returns(draftMock.Object);
  • 能否请您分享此异常的堆栈跟踪/内部异常。另外,您在哪里将您的模拟数据库上下文注册到测试项目中的接口?
  • @TylerHundley.. 它不工作...感谢您的回复
  • @Saravanan... 添加了您在哪里将您的模拟数据库上下文注册到测试项目中的接口? ==> 我想我没有注册它
  • 如果你也尝试模拟AsNoTracking?我认为这是问题所在,因为该方法返回null,例如:draftMock.Setup(x =&gt; x.AsNoTracking()).Returns(draftMock.Object)

标签: c# entity-framework unit-testing moq autofac


【解决方案1】:

你快到了,DbSet 被正确地模拟了,但是查看方法,你会注意到 AsNoTracing 方法实际上没有被模拟,它返回 null

lstDraftProj = (from proj in mydbEntities.getProjectsDrafts.AsNoTracking()
                orderby proj.ProjectID descending
                select proj).ToList();

堆栈跟踪也建议这样做:

System.ArgumentNullException HResult=0x80004003 消息= 不能为空。参数名称:来源

既然您已经在模拟 DbSet,请尝试模拟 AsNoTracing 方法,例如:

draftMock.Setup(x => x.AsNoTracking()).Returns(draftMock.Object)

【讨论】:

    猜你喜欢
    • 2017-01-19
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    相关资源
    最近更新 更多