如何Mock Context.Database.SqlQuery<Books>语句以进行单元测试?
如何Mock Context.Database.SqlQuery进行单元测试
下面针对你提到的两种代码场景,用Moq框架实现Mock,完成单元测试:
场景1:Mock Context.Database.SqlQuery<Books>("select * from book")
步骤说明
- 准备测试用的Books数据集
- 模拟
DbRawSqlQuery<Books>(SqlQuery<T>方法返回该类型,它实现了IEnumerable<T>) - 模拟
Database对象,让其SqlQuery<Books>方法返回上述模拟实例 - 模拟
DbContext,让其Database属性指向模拟的Database对象
代码示例
// 准备测试数据 var testBooks = new List<Books> { new Books { Id = 1, Title = "测试书籍1" }, new Books { Id = 2, Title = "测试书籍2" } }; // 模拟DbRawSqlQuery<Books> var mockSqlQuery = new Mock<DbRawSqlQuery<Books>>(); mockSqlQuery.As<IEnumerable<Books>>() .Setup(q => q.GetEnumerator()) .Returns(testBooks.GetEnumerator()); // 模拟Database对象,匹配目标SQL语句 var mockDatabase = new Mock<DbDatabase>(); mockDatabase.Setup(db => db.SqlQuery<Books>("select * from book", It.IsAny<object[]>())) .Returns(mockSqlQuery.Object); // 模拟DbContext var mockContext = new Mock<YourDbContext>(); mockContext.Setup(c => c.Database).Returns(mockDatabase.Object); // 执行测试并断言 var result = mockContext.Object.Database.SqlQuery<Books>("select * from book"); Assert.Equal(2, result.Count());
场景2:Mock Context.Database.SqlQuery<Books>("select statement").ToList()
该场景核心逻辑和场景1一致,ToList()是对SqlQuery<T>返回的IEnumerable<T>执行的操作,只要模拟的SqlQuery<T>返回正确的集合数据,ToList()就能得到预期列表。
代码示例
// 准备测试数据 var testBooks = new List<Books> { new Books { Id = 3, Title = "测试书籍3" }, new Books { Id = 4, Title = "测试书籍4" } }; // 模拟DbRawSqlQuery<Books> var mockSqlQuery = new Mock<DbRawSqlQuery<Books>>(); mockSqlQuery.As<IEnumerable<Books>>() .Setup(q => q.GetEnumerator()) .Returns(testBooks.GetEnumerator()); // 模拟Database对象 var mockDatabase = new Mock<DbDatabase>(); mockDatabase.Setup(db => db.SqlQuery<Books>("select statement", It.IsAny<object[]>())) .Returns(mockSqlQuery.Object); // 模拟DbContext var mockContext = new Mock<YourDbContext>(); mockContext.Setup(c => c.Database).Returns(mockDatabase.Object); // 执行测试并断言 var resultList = mockContext.Object.Database.SqlQuery<Books>("select statement").ToList(); Assert.Equal(2, resultList.Count); Assert.Equal("测试书籍3", resultList[0].Title);
注意事项
- 确保项目已安装Moq NuGet包(
Install-Package Moq) - 若使用EF Core,
SqlQuery相关类型略有差异,需调整为FromSqlRaw对应的Mock逻辑,但核心思路一致:模拟返回的枚举集合 - 如需匹配带参数的SQL语句,可将
It.IsAny<object[]>()替换为具体参数数组,或用It.Is<object[]>(p => ...)做精确匹配
内容的提问来源于stack exchange,提问作者Brandon Michael Hunter
相关产品推荐
相关产品推荐

