2 Stimmen

System.Data.Linq.Table in Code zum Testen erstellen

Ich habe eine Adapterklasse für Linq-to-Sql:

public interface IAdapter : IDisposable
{
    Table<Data.User> Activities { get; }
}

Data.User ist ein von Linq-to-Sql definiertes Objekt, das auf die Tabelle User in der Persistenz verweist.

Die Umsetzung sieht folgendermaßen aus:

public class Adapter : IAdapter
{
    private readonly SecretDataContext _context = new SecretDataContext();

    public void Dispose()
    {
        _context.Dispose();
    }

    public Table<Data.User> Users
    {
        get { return _context.Users; }
    }
}

Dies macht das Mocking der Persistenzschicht in Unit-Tests einfach, da ich einfach eine beliebige Sammlung von Daten für Benutzer zurückgeben kann (Rhino.Mocks):

Expect.Call(_adapter.Users).Return(users);

Das Problem ist, dass ich das Objekt "users" nicht erstellen kann, da die Konstruktoren nicht zugänglich sind und die Klasse Table versiegelt ist. Eine Möglichkeit, die ich ausprobiert habe, ist, IAdapter einfach IEnumerable oder IQueryable zurückgeben zu lassen, aber das Problem dabei ist, dass ich dann keinen Zugriff auf die Methoden habe, die ITable bietet (z. B. InsertOnSubmit()). Gibt es eine Möglichkeit, wie ich die gefälschte Tabelle im Unit-Test-Szenario erstellen kann, so dass ich ein glücklicher TDD-Entwickler sein kann?

0voto

Doctor Blue Punkte 3528

Meine aktuelle Lösung ist es, die Funktionalität, die ich von Tabelle in eine TableWrapper-Klasse verpacken möchten:

public interface ITableWrapper<TEntity> 
    where TEntity : class
{
    IEnumerable<TEntity> Collection { get; }
    void InsertOnSubmit(TEntity entity);
}

Und hier ist die Umsetzung:

public class TableWrapper<TEntity> : ITableWrapper<TEntity> 
    where TEntity : class
{
    private readonly Table<TEntity> _table;

    public TableWrapper(Table<TEntity> table)
    {
        _table = table;
    }

    public IEnumerable<TEntity> Collection
    {
        get { return _table; }
    }

    public void InsertOnSubmit(TEntity entity)
    {
        _table.InsertOnSubmit(entity);
    }
}

So kann ich jetzt einfach Daten aus der Sammlung spiegeln und die Funktionalität von InsertOnSubmit beibehalten (andere Funktionen, die ich später benötige, können später hinzugefügt werden).

0voto

Tormod Punkte 4245

Ich hatte Erfolg bei der Verwendung der Datenzugriffsschicht, um Domänenobjektsammlungen zu erstellen und dann Linq zu Objekten zu verwenden. Das zu testende Objekt bezieht sich dann nur auf List, was ziemlich einfach zu testen ist.

Ich mag es nicht, wenn die logischen Entitäten Abhängigkeiten von der Datenzugriffsschicht haben sollten. Sie sollten an der Serviceschicht aufhören, wenn sie überhaupt dort sind. In der Regel entscheide ich mich für das Modell, bei dem die Serviceschicht ein Datenzugriffsobjekt aufruft, um eine Liste zu erhalten, und diese Liste an ein beliebiges Logikobjekt weitergibt, das sie benötigt (ggf. unter Verwendung von linq-to-objects, um die relevanten Daten herauszufiltern, und sie in eine flache Liste, ein Wörterbuch oder ein Objektmodell injiziert).

Die Geschäftsobjekte werden sehr gut testbar, auch wenn sie nicht von der Reichhaltigkeit des abgeleiteten Datenmodells profitieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X