2017-11-17 2 views
0

Ich bin neu im Schreiben von Tests und Mock. Ich versuche herauszufinden, wie man Raw SQL nachahmen kann, um Daten abzurufen. Hier ist, was ich habe:Wie sqlQuery zu verspotten

Ich habe DataContext.cs

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

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

Ich habe Controller 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; 
     } 
    } 
} 

Und ich habe 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(); 
} 

Ich kann Abrufen von Daten unter Verwendung von Linq (test2) aber mit SqlQuery bekomme ich immer null (test). Wie ändere ich das mit SqlQuery? Ich bekomme dasselbe Ergebnis wie mit Linq? Ich werde auch wissen, dass das Erstellen von InMemory-Datenbank tatsächlich einige Listen (Typ = IQueriable) im Hintergrund, nicht Datenbank erstellt. Können Sie bitte eine Erklärung und eine Lösung für dieses Problem geben?

+0

Was verspotten Sie? Raw SQL entfernt alle Dependency-Abhängigkeiten und lässt Ihnen nichts zum Nachsinnen. Was versuchst du zu testen? – lloyd

+0

Ich sollte Code bearbeiten. Ich möchte nur testen, ob ich Ergebnisse von der GetBooks() Methode bekomme. Wenn ich den Test debugge, springt es in die Methode GetBooks(), dann wird die Variable "test" null, während "test2" die erforderlichen Daten erhält. Ok, wie rohe SQL-Anweisung zu testen? – Rok

Antwort

2

Wie wäre es damit. (nicht sicher, ob ich Ihre Frage richtig verstehe)

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

In diesem Beispiel wird davon ausgegangen, dass alle Abfragen alle Elemente zurückgeben.

+0

Ich habe versucht und sieht besser aus, "Test" gibt ein Objekt zurück, aber die Ergebnisansicht gibt "Enumeration ergab keine Ergebnisse" zurück, während "Test2" (Linq) normalerweise tut. Aber es ist ein Schritt nach vorne, ich denke, ich brauche nur ein bisschen zusätzliches Wissen, um dieses Ding zu erledigen. Vielen Dank – Rok