Erstellen Sie eine gespeicherte Prozedur in der Effort-Datenbank für den Komponententest

c# effort entity-framework stored-procedures unit-testing

Frage

Ich habe eine Funktion, die eine gespeicherte Prozedur mit Entity Framework aufruft:

public async Task<List<Entity>> GetEntity(int id)
{
       var param = new SqlParameter("@id", id);
       return await myContext.Database
           .SqlQuery<MyEntity>("[myStoredProcedure] @id", param)
           .ToListAsync();
}

Und ich möchte mit Effort einen Komponententest dafür erstellen. Ich habe bereits Effort (und NMemory-Datenbank), um eine Datenbank zu simulieren (basierend auf meinem Kontext), auf Initialize für jeden Einheitentest, wie:

[TestInitialize]
public void Initialize()
{
     Effort.Provider.EffortProviderConfiguration.RegisterProvider();
     EffortProviderFactory.ResetDb()
     using (var context = new MyContext("PWET"))
     {
          context.Database.CreateIfNotExists();
          context.Constructeurs.Add(new Constructeur { Nom = "Zebra" });
          context.Constructeurs.Add(new Constructeur { Nom = "Joya" });
          context.SaveChanges();
     }
}

Wo ist EffortProviderFactory :

public class EffortProviderFactory : IDbConnectionFactory
{
    private static DbConnection _connection;
    private readonly static object _lock = new object();

    public static void ResetDb(){
        lock (_lock){
            _connection = null;
        }
    }
    public DbConnection CreateConnection(string nameOrConnectionString)
    {
        lock (_lock){
            if (_connection == null)
                _connection = Effort.DbConnectionFactory.CreateTransient();
            return _connection;
        }
    }
}

Ich habe das Hinzufügen der gespeicherten Prozedur wie folgt getestet:

[TestInitialize]
public void Initialize()
{
     Effort.Provider.EffortProviderConfiguration.RegisterProvider();
     EffortProviderFactory.ResetDb()
     using (var context = new MyContext("PWET"))
     {
          context.Database.CreateIfNotExists();
          context.Database.ExecuteSqlCommand(@"
CREATE PROCEDURE [dbo].[myStoredProcedure]
@id INT = 0
AS
BEGIN

SELECT foo
FROM bar 
WHERE foo.Id = @id

ORDER BY foo.Id;
END");
     }
}

Aber es NotSupportedException eine NotSupportedException . Wie kann ich und was ist der beste Weg?

Akzeptierte Antwort

Effort ist ein dateibasierter In-Memory-Datenbankanbieter, der eine DbContext Instanz mit einer temporären Datenbank in Privatbesitz versorgt: Neuer Kontext, neue Datenbank, keine DbContext . Das ist der gute Teil.

Der Nachteil ist natürlich, dass es sich nicht um eine vollwertige Datenbank handelt. Daher wird es niemals gespeicherte Prozeduren unterstützen, die in einem der gängigen SQL-Dialekte (wie t-SQL oder PL-SQL) geschrieben sind. Soweit "Effort" (dh NMemory) Prozeduren gespeichert hat, ist es nur ein gespeichertes IQueryable , wie aus dem StoredProcedure Konstruktor hervorgeht . Remote-Bezug zu gespeicherten t-SQL-Prozeduren feststellen.

Die einzige Möglichkeit, gespeicherte Prozeduren in Ihrem Datenzugriffsschichtcode zu testen, was eine sehr gute Idee ist, ist das Schreiben von Integrationstests. Es gibt in etwa zwei Ansätze, Integrationstests unabhängig voneinander zu machen:

  • Erstellen / seed eine neue Datenbank für jeden Test

  • Verwenden Sie eine vorhandene Datenbank mit Testfällen, und führen Sie nach jedem Test Änderungen zurück, z. B. mit TransactionScope .

Integrationstests werden nie so schnell sein wie Komponententests und sie ergänzen nur Komponententests. Dennoch sind sie in meiner eigenen Kodierungspraxis in Bezug auf Datenschichten zu erstklassigen Bürgern in der Testsuite geworden. Für mich ist Korrektheit wichtiger als Geschwindigkeit.




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum