Entity Framework Core :
.NET Framework / EF Core 3.1 / Sqlite / xunit
Entity Framework Core permet d'exécuter des tests unitaires par l'intermédiaire de Sqlite. Cela fonctionne simplement en .NET Core, mais en .NET Framework, c'est une autre histoire.
Avertissement : Entity Framework Core 3.1 n'est plus supporté.
Problème
Lorsque l'on créait un projet créait un projet de test unitaire avec Entity Framework Core Sqlite en .NET Framework :
dotnet new xunit --name Demo.Tests --framework netcoreapp3.1 --target-framework-override net48 cd Demo.Tests dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 3.1.31 dotnet restore --ignore-failed-sources dotnet test
Puisque l'on écrit un test utilisant Sqlite. Par exemple :
using Microsoft.EntityFrameworkCore; using Xunit; namespace Demo.Tests { public class UnitTest1 { [Fact] public void Test1() { var context = new DemoContext(); context.Database.EnsureCreated(); } } public class DemoContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("Data Source=:memory:"); } } }
Lorsque le test est exécuté :
> dotnet test ... [xUnit.net 00:00:02.62] Demo.Tests.UnitTest1.Test1 [FAIL] Failed Demo.Tests.UnitTest1.Test1 [1 s] Error Message: System.TypeInitializationException : The type initializer for 'Microsoft.Data.Sqlite.SqliteConnection' threw an exception. ---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. -------- System.Exception : Library e_sqlite3 not found ... Failed! - Failed: 1, Passed: 0, Skipped: 0, Total: 1, Duration: - Demo.Tests.dll (net48)
L'erreur "Library e_sqlite3 not found" survient.
Analyse
Ce problème est référencé dans le ticket GitHub :
[.Net Framework 4.8]Library e_sqlite3 not found
En résumé, l'exécuteur de test xunit exécute les tests en Shadow Copy par défaut... seulement les composants nécessaires à Sqlite ne semblent pas correctement copiés.
Shadow Copy, quésaco?
En .NET, lorsqu'un assemblie est chargé, le fichier associé est verrouillé et il n'est pas possible de le modifier.
Le Shadow Copy indique à la runtime d'effectuer une copie des assemblies dans un dossier temporaire pour les charger depuis ce dossier. Ainsi le fichier originel n'est pas verrouillé.
Solution
Pour éviter ce problème, il suffit de désactiver le Shadow Copy à l'exécution des tests. Pour cela, il faut ajouter au côté du csproj le fichier "xunit.runner.json" avec le contenu suivant :
{ "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", "shadowCopy": false }
One possible testing approach is to swap your production database with SQLite, effectively using it as a testing "fake".
Une approche possible pour tester consiste à substituer le système de gestion de base de données (SGBD) par SQLite, en l'utilisant comme une base de données factice.