2009-08-06 20 views
2

Ich habe zwei Tabellen, Clients und Administratoren, die in einer Viele-zu-Viele-Beziehung durch die Tabelle ClientAdministrators verbunden sind.LINQ to SQL: Gefälschtes Repository mit vielen-zu-vielen Beziehungen?

In der realen Anwendung funktioniert das gut und ich kann eine Liste der Administratoren für meinen Client erhalten. Mein Problem tritt auf, wenn versucht wird, die Serviceklasse, die diese aus dem Repository abruft, in einem Unit-Test zu testen.

Ich habe eine FakeRepository-Klasse, die meine Repository-Schnittstelle implementiert, und ich habe mehrere interne Listen von Objekten für die Dienstklasse abzufragen.

Mein Problem ist, dass ich keinen Weg finden kann, die Beziehungen in den falschen Klassen funktionieren zu lassen, um erfolgreich gegen diese Viele-zu-Viele-Beziehung abfragen zu können.

Dim clients = From c in _repository.GetAllClients _ 
       Select New ClientBizObj With {.ID = c.ID, _ 
              .ClientName = c.ClientName, _ 
              .Admins = (From a in c.ClientAdministrators _ 
                 Select a.Administrator.UserName).ToList} 

Es sagt mir, dass c.ClientAdministrators ein EntitySet ist (von ClientAdministrator).

Wie kann ich diese Beziehung in meiner FakeRepository-Klasse fälschen, so dass sie NullReferenceExceptions wirft?

Es ist mir egal, wenn keine Admins zurückgibt, ich brauche nur das Client-Objekt erfolgreich zurückgegeben werden.

Antwort

2

In Ihrem Beispiel versuchen Sie speziell, die Datenzugriffsebene zu überspielen, nicht die Datenbankoperationen selbst. Dies ist beim Komponententest vollkommen legitim, um Ihre Logik von Persistenzanliegen zu isolieren.

Das von Ihnen beschriebene Problem kann gelöst werden, indem Sie eine Kopie Ihrer Client-Klasse erstellen. In diesem Mock können Sie die ClientAdministrators-Eigenschaft überschreiben, um eine leere Auflistung zurückzugeben und dennoch alles andere an die reale Klasse zu delegieren. Sie benötigen dann Ihre FakeRepository-Klasse, um Ihre Mock anstelle der realen Clients-Klasse zurückzugeben.

Mehrere Mock-Tools existieren, um dies einfach zu machen. Unter diesen ist eine der am einfachsten zu verwendenden (und Open Source zum Booten) moq. Mit moq sollten Sie in der Lage sein, Ihre gesamte Datenzugriffsebene für Tests zu testen, sodass Sie nicht einmal Ihre eigene FakeRepository-Klasse erstellen müssen.

+0

Ich bin sicher, die Antwort liegt in dieser Richtung. Ich denke, was dies schwierig macht ist, dass GetAllClients() ein IQueryable statt IEnumerable zurückgibt und so die Sub-Abfrage erweist sich als schwer zu verspotten. Wenn Sie mir ein Beispiel dafür geben können, wäre ich sehr dankbar. – Nick

+1

OK, klingt, als wären Sie nah dran.Wenn Ihr Mock einen IEnumerable erstellen kann und Sie LINQ referenzieren, können Sie Ihren enumerable.AsQueryable() oder AsQueryable () zurückgeben. –

2

Dies muss einer der Gründe sein, dass Roy Osherove (Chefarchitekt bei TypeMock und Autor des Buches "The Art of Unit Testing") empfiehlt, dass Datenbankoperationen nicht verspottet werden. Er empfiehlt, dass ein solcher Test relegated to the integration tests ist und dass die tatsächliche Datenbank an solchen Tests beteiligt sein sollte.

1

können Sie verwenden Dev Magie Fake Fake-DB nicht DB zu verspotten, in anderen Worten Sie die UI Mock kann, durch die folgenden Schritte ausführen:

[HttpPost] 
public ActionResult Create(Client model) 
{ 
    var repository = new FakeRepository<Client>(); 
    repository.Save(model) 

Weitere Informationen finden Sie DevMagicFake auf CodePlex

devmagicfake.codeplex.com

Dank

M.Radwan