c# – 如何Moq实体框架SqlQuery调用

前端之家收集整理的这篇文章主要介绍了c# – 如何Moq实体框架SqlQuery调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经能够使用这个 link从Moq的实体框架中模拟DbSet.

但是,我现在想知道如何可以模拟对sqlQuery的调用.不知道这是可能的,还是如何依赖于嘲弄的数据库环境,知道正在调用什么“查询”.

下面是我试图嘲笑的.

var myObjects = DbContext.Database
    .sqlQuery<MyObject>("exec [dbo].[my_sproc] {0}","some_value")
    .ToList();

我目前没有尝试任何东西,因为不知道如何开始嘲笑这个例子.

DbSet的嘲笑在下面并重新迭代,我可以正确地模拟返回MyObject的DbSet,但现在我试图模拟一个返回MyObject列表的sqlQuery.

var dbContext = new Mock<MyDbContext>();
dbContext.Setup(m => m.MyObjects).Returns(mockObjects.Object);

dbContext.Setup(m => m.Database.sqlQuery... something along these lines

解决方法

Database.SqlQuery<T>标记为虚拟,但 Set<T>.SqlQuery标记为虚拟.

基于Database.SqlQuery<T>文档

The results of this query are never tracked by the context even if the
type of object returned is an entity type. Use the 07003 method to return entities that are tracked by the
context.

Set<T>.SqlQuery文档

By default,the entities returned are tracked by the context; this can
be changed by calling AsNoTracking on the DbRawsqlQuery returned.

那么Database.sqlQuery< T>(String,Object [])应该与Set< T> .sqlQuery(String,Object [])等同.AsNoTracking()(只有当T是EF实体,而不是DTO / VM) .

所以如果你可以将实现替换成:

var myObjects = DbContext
    .Set<MyObject>()
    .sqlQuery("exec [dbo].[my_sproc] {0}","some_value")
    .AsNoTracking()
    .ToList();

你可以嘲笑它如下

var list = new[] 
{ 
    new MyObject { Property = "some_value" },new MyObject { Property = "some_value" },new MyObject { Property = "another_value" }
};

var setMock = new Mock<DbSet<MyObject>>();
setMock.Setup(m => m.sqlQuery(It.IsAny<string>(),It.IsAny<object[]>()))
    .Returns<string,object[]>((sql,param) => 
    {
        // Filters by property.
        var filteredList = param.Length == 1 
            ? list.Where(x => x.Property == param[0] as string) 
            : list;
        var sqlQueryMock = new Mock<DbsqlQuery<MyObject>>();
        sqlQueryMock.Setup(m => m.AsNoTracking())
            .Returns(sqlQueryMock.Object);
        sqlQueryMock.Setup(m => m.GetEnumerator())
            .Returns(filteredList.GetEnumerator());
        return sqlQueryMock.Object;
    });

var contextMock = new Mock<MyDbContext>();
contextMock.Setup(m => m.Set<MyObject>()).Returns(setMock.Object);

猜你在找的C#相关文章