6 Stimmen

Wie man DataReader zu Einheitstest DAL spottet

Ich habe eine Methode in meiner Datenzugriffsschicht, die Mapping durchführt. Die Methode akzeptiert einen DataReader und ordnet die Daten den richtigen Domänenobjekteigenschaften zu. Gibt es eine gute Möglichkeit, irgendwie mock der DataReader, so dass ich Unit-Tests auf die Mapping-Methoden durchführen können, ohne gegen eine physische Datenbank zu schlagen?

11voto

Jay Punkte 53725

Zum Glück für Sie, DataReader implementiert die IDataReader Schnittstelle.

Anstatt sich auf eine DataReader in Ihrem Code, verwenden Sie IDataReader . In Ihren Tests können Sie dann Ihre eigene Implementierung ersetzen, die Dummy-Daten zurückgibt, oder Sie verwenden ein Mocking-Framework wie Rhino.Mocks oder ähnliches, um die Stubs zu erstellen und Rückgabewerte zuzuweisen.

Je nachdem, wie Sie die DataReader in Ihrem Code zu finden, müssen Sie möglicherweise eine kleine Umstrukturierung vornehmen. Was Sie wollen, ist, dass externe Abhängigkeiten wie diese in den Konstruktor (bevorzugt) oder durch eine Eigenschaft "injiziert" werden, so dass die Benutzer der Klasse jede Implementierung von IDataReader . (Diese Substitution ist auch der Grund, warum Sie Ihre Parameter/Eigenschaften als Abstraktionen und nicht als konkrete Typen deklarieren). Dies ist bekannt als Injektion von Abhängigkeiten , eine Form der Umkehrung der Kontrolle .

4voto

Param Punkte 41

Wenn Sie den IDataReader nachahmen wollen, um eine Liste von Datensätzen zurückzugeben, können Sie eine Klasse erstellen, die IDataReader implementiert und einige ihrer Methoden (wie Read() und Indexer) außer Kraft setzen. Außerdem benötigen Sie eine Variable, die die aktuelle Zeile aufzeichnet, und eine Variable, die die Listenwerte enthält. Nachfolgend finden Sie den Beispielcode für diese Vorgehensweise:

public class MockDataReader : IDataReader
{
    private int _rowCounter = 0;
    private List<Dictionary<string,object>> _records = new List<Dictionary<string,object>>();

    public MockDataReader(List<Dictionary<string,object>> records)
    {
        _records = records;
    }

    public bool Read()
    {
        _rowCounter++;
        if (_rowCounter < _records.Count) return true;
        return false;
    }

    public object this[string name]
    {
        get { return _records[_rowCounter][name]; }
    }
}

Um diese Klasse zu nutzen, können Sie den folgenden Code verwenden:

var itemsList = new List<Dictionary<string, object>>();
for (int i = 0; i < 5; i++)
{
    var num = i + 1;
    var items = new Dictionary<string, object>();
    items.Add("Id", num);
    items.Add("FirstName", "MyFirstName" + num);
    items.Add("LastName", "MyLastName" + num);
    itemsList.Add(items);
}

var result = new MockDataReader(itemsList); 

Das ist nicht ganz sicher, aber es funktioniert. Ich hoffe, es hilft :)

3voto

Darin Dimitrov Punkte 990883

Ja, verwenden Sie nicht DataReader pero IDataReader o IDataRecord dann spottet, was ihr wollt.

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