2010-08-21 20 views
15

Ich möchte Integrationstests meiner Entity Framework-basierten Repositorys implementieren. Das Problem besteht darin, wie der Datenbankstatus nach Abschluss der Tests zurückgesetzt wird. Im Moment plane ich, die Transaktion beim Test SetUp zu starten und sie beim Test TearDown zurückzuspielen. Gibt es andere Lösungen als das manuelle Löschen von Datenbanken?Rollback ausführen - Repository-Integrationstests

Antwort

21

Das machen wir in unseren Integrationstests mit MSTest. Wir verwenden den TransactionScope und implementieren einen Testaufbau und Teardown in einer Basisklasse. Auf diese Weise können Sie alle Integrationstests innerhalb einer Transaktion ausführen. Die Basisklasse sieht ungefähr so ​​aus:

public class IntegrationTestsBase 
{ 
    private TransactionScope scope; 

    [TestInitialize] 
    public void Initialize() 
    { 
     this.scope = new TransactionScope(); 
    } 

    [TestCleanup] 
    public void TestCleanup() 
    { 
     this.scope.Dispose(); 
    } 
} 

Viel Glück.

+0

Very nice! Nun, wenn es nur für Oracle funktioniert ... –

+0

Soweit ich weiß, funktioniert das 'TransactionScope' mit Oracle. Es wurde speziell für die Multi-Vendor-Kommunikation mehrerer Hersteller (Zwei-Phasen-Commits) entwickelt. – Steven

+2

Ok und nach Repo.Save (someObject) im Test wie überprüfen Sie, ob das Objekt gespeichert wurde? –

2

Das ist wahrscheinlich der einfachste Weg, die andere Möglichkeit besteht darin, die Datenbank bei SetUp neu aufzubauen.

5

Ich glaube, Sie auf dem richtigen Weg sind ....

Here's an example doing the same with Linq To SQL that you can tweek for yourself.

This link describes three options:

  • Transaktionen
  • Neuerstellen der DB
  • Verwenden Sie SQL Server-Snapshots

Der Beitrag geht weiter, um zu beschreiben, dass Transaktionen während der schnellsten an eine einzelne Sitzung gebunden sind und einige echte Probleme/Einschränkungen schaffen können. Verwenden Sie, wenn Sie können ....

Wiederaufbau der DB ist langsam aber definitiv machbar, aber mit Snapshots ist schnell und umgeht die Transaktionsbeschränkungen.

Wenn Sie eine sehr hohe Leistung in Ihren automatisierten Tests benötigen try this from the same blogger. Er beschreibt die Verwendung von MS Distributed Transaction Coordinator, um die Transaktionsbeschränkungen einer einzelnen Sitzung zu eliminieren.

4

Das Problem beim Öffnen von TransactionScope in Setup und Dispose in TearDown ist, dass Sie das Commit NICHT testen!

+1

Wenn Sie das Commit nicht testen, ist der gesamte Test ein halber Integrationstest ... – Pascal

0

Der beste Weg ist ein transaktionaler Ansatz. Die Verbindung, die ich zur Verfügung gestellt habe, enthält einen kurzen Spaziergang. Fast jede Unternehmenslösung, mit der ich in Kontakt gekommen bin, verwendet einen transaktionsbasierten Ansatz. Sehen Sie sich auch die Links am Ende des Artikels an, die Links zu Microsofts Dokumentation zu Transaktionen mit Entity-Framework enthalten. Die anderen Optionen, die oben aufgelistet sind, konkurrieren Overkill in einem einfachen Konzept der Bereinigung einer Testtransaktion. Das Erstellen einer Datenbank oder das Verwenden von Server-Snapshots ist ein kompletter Overkill für dieses Problem. TransactionScope führt die Transaktion nicht einmal aus, wodurch ein Integrationstest nicht abgeschlossen wird. Implementieren

Transaktionen

Dies erzeugt eine Transaktion vor jedem Test startet und Rollback der Transaktion nach jedem Test endet.

[TestClass] 
public class TransactionTest 
{ 
    protected EntitiesV3 context; 
    protected DbContextTransaction transaction; 

    [AssemblyInitialize] 
    public static void AssemblyStart(TestContext testContext) 
    { 
    RetryDbConfiguration.SuspendExecutionStrategy = true; 
    } 

    [TestInitialize] 
    public void TransactionTestStart() 
    { 
    context = new EntitiesV3(); 
    transaction = context.Database.BeginTransaction(); 
    } 

    [TestCleanup] 
    public void TransactionTestEnd() 
    { 
    transaction.Rollback(); 
    transaction.Dispose(); 
    context.Dispose(); 
    } 

    [AssemblyCleanup] 
    public static void AssemblyEnd() 
    { 
    RetryDbConfiguration.SuspendExecutionStrategy = false; 
    } 
} 

Great quick walk through on transactional rollback/cleanup approach