简体   繁体   English

如何模拟SqlQuery

[英]How to mock SqlQuery

I'm new in writing tests and Mock. 我是编写测试和Mock的新手。 I'm trying to figure it out how to mock Raw SQL to retrieve data. 我试图弄清楚如何模拟Raw SQL来检索数据。 Here's what I have: 这是我所拥有的:

I have DataContext.cs 我有DataContext.cs

public class DataContext : DbContext
{
    public DataContext() 
         : base("Main")
    {
    }

    public virtual DbSet<DbBook> Books { get; set; }
    public virtual DbSet<DbMovie> Movies { get; set; }
}

I have controller BooksController.cs 我有控制器BooksController.cs

public class BooksController : ApiController
{
    private readonly BookDataContext _db;
    public BooksController ()
    {
        _db = new BookDataContext();
    }

    public BooksController (BookDataContext context)
    {
        _db = context;
    }

    [HttpGet]
    [Route("books")]
    public Book GetBooks()
    {
        using (var dbContextTransaction = _db.Database.BeginTransaction())
        {
            var test = _db.Books.SqlQuery("select * from BOOK");
            var test2 = from b in _db.Books
                            orderby b.Books
                            select b;
        }
    }
}

And I have test 我有测试

[TestMethod]
public void GetBook()
{
    var data = new List<DbBook>
    {
        new DbBook{ Book = "Book1"},
        new DbBook{ Book = "Book2"}
    }.AsQueryable();

    var mockSet = new Mock<DbSet<DbScriptId>>();
    mockSet.As<IQueryable<DbBook>>().Setup(m => 
    m.Provider).Returns(data.Provider);
    mockSet.As<IQueryable<DbBook>>().Setup(m => 
    m.Expression).Returns(data.Expression);
    mockSet.As<IQueryable<DbBook>>().Setup(m => 
    m.ElementType).Returns(data.ElementType);
    mockSet.As<IQueryable<DbBook>>().Setup(m => 
    m.GetEnumerator()).Returns(data.GetEnumerator());
    mockSet.Setup(m => m.Find(It.IsAny<object[]>()))
         .Returns<object[]>(sc => data.SingleOrDefault());


    var mockContext = new Mock<DataContext>();
    mockContext.Setup(c => c.Books).Returns(mockSet.Object);

    var controller = new BooksController (mockContext.Object);
    var books = controller.GetBook();
}

I can retrieve data using Linq (test2) but using SqlQuery I always get null (test). 我可以使用Linq(test2)检索数据,但是使用SqlQuery总是得到null(测试)。 How to change that using SqlQuery I get same result as using Linq? 如何使用SqlQuery更改与使用Linq得到的结果相同的结果? Also I'm getting to know that creating InMemory database actually creates some lists (type=IQueriable) in background, not database. 我也知道创建InMemory数据库实际上是在后台而不是数据库中创建一些列表(type = IQueriable)。 Can you please provide some explanation and resolution for this issue? 您能否对此问题提供一些解释和解决方案?

How about this. 这个怎么样。 (not sure if I understand your question right) (不确定我是否理解您的问题)

 var queryMock = new Mock<DbSqlQuery<DbBook>>();
 queryMock.Setup(x => x.GetEnumerator()).Returns(data.GetEnumerator());

 mockSet.Setup(m => m.SqlQuery(It.IsAny<string>(), It.IsAny<object[]>())).Returns(queryMock.Object);

This example assumes that all queries will return all items. 本示例假定所有查询将返回所有项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM