如何模拟SqlQuery

时间:2017-11-17 09:35:57

标签: c# linq unit-testing

我是编写测试和模拟的新手。我试图找出如何模拟Raw SQL来检索数据。这就是我所拥有的:

我有DataContext.cs

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

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

我有控制器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;
        }
    }
}

我有测试

[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();
}

我可以使用Linq(test2)检索数据但是使用SqlQuery我总是得到null(测试)。如何使用SqlQuery更改它我得到与使用Linq相同的结果?另外我知道创建InMemory数据库实际上在后台创建了一些列表(type = IQueriable),而不是数据库。你能否就这个问题提供一些解释和解决方案?

1 个答案:

答案 0 :(得分:2)

这个怎么样? (不确定我是否理解你的问题)

 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);

此示例假定所有查询都将返回所有项目。