Auf einem C # -Server mit SQL Server und PetaPoco haben wir diesen Ansatz gewählt, um Daten in Unit-Tests zu bereinigen.
Ein typischer Unit-Test hätte Setup und Teardown wie folgt:
[TestFixture]
internal class PlatformDataObjectTests
{
private IDatabaseConfiguration _dbConfig;
private Database _pocoDatabase;
private PlatformDataObject _platformDto;
[SetUp]
public void Setup()
{
_dbConfig = new CommonTestsAppConfig().GetDatabaseConfiguration();
_pocoDatabase = new Database(_dbConfig.ConnectionString, SqlClientFactory.Instance);
_platformDto = new PlatformDataObject(_pocoDatabase);
_platformDto.BeginTransaction();
}
[TearDown]
public void TearDown()
{
Console.WriteLine("Last Sql: {0}", _pocoDatabase.LastCommand);
_platformDto.RollbackTransaction();
_platformDto.Dispose();
}
// ...
}
Wobei PlatformDataObject eine Klasse ist, die für die Kommunikation mit der Datenbank verantwortlich ist, z. B. für Select Insert Update Deletes. Alle * DataObject-Typen erben ServerDataObject - die Basisklasse verfügt über Methoden zum Abbrechen, Zurücksetzen oder Festschreiben der Transaktion.
/// <summary>
/// A Data-Transfer Object which allows creation and querying of Platform types from the database
/// </summary>
[ExportType(typeof(IPlatformDataObject))]
public class PlatformDataObject : ServerDataObject, IPlatformDataObject
{
private static readonly ILog Log = LogManager.GetLogger(typeof (ProductDataObject));
private const string PlatformTable = "t_Platform";
public PlatformDataObject(IPocoDatabase pocoDatabase) : base(pocoDatabase)
{
}
...
}
/// <summary>
/// A base Data-Transfer Object type
/// </summary>
public abstract class ServerDataObject : IServerDataObject
{
protected const string Star = "*";
private readonly IPocoDatabase _pocoDatabase;
public ServerDataObject(IPocoDatabase pocoDatabase)
{
_pocoDatabase = pocoDatabase;
}
public string LastCommand
{
get { return PocoDatabase.LastCommand; }
}
public IPocoDatabase PocoDatabase
{
get { return _pocoDatabase; }
}
public int TransactionDepth
{
get { return _pocoDatabase.TransactionDepth; }
}
public bool TransactionAborted { get; private set; }
public void BeginTransaction()
{
_pocoDatabase.BeginTransaction();
}
public void AbortTransaction()
{
_pocoDatabase.AbortTransaction();
}
public void RollbackTransaction()
{
TransactionAborted = true;
}
public virtual void Dispose()
{
if (TransactionAborted)
_pocoDatabase.AbortTransaction();
else
_pocoDatabase.CompleteTransaction();
}
}
Alle Komponententests würden RollbackTransaction () aufrufen und letztendlich IDbTransaction.Rollback () aufrufen.
In Tests haben wir festgestellt, dass es Routine ist, eine neue Instanz eines * DataObject zu erstellen, einige Zeilen mit Insert-Anweisungen zu erstellen, Tests für sie durchzuführen (Selects, Updates usw.) und dann ein Rollback durchzuführen.
Wir können eine Reihe von Testdaten einrichten, bevor alle Tests mit einem SetUpFixture ausgeführt werden - eine Klasse, die einmal ausgeführt wird, bevor alle Tests ausgeführt werden, und die Daten beim Herunterfahren löschen / zurücksetzen, nachdem alle Tests ausgeführt wurden.