I have pain to understand how to unit test with EF in a concrete example. Things seem half explained everywhere.
in my real word example I have a class with method.
namespace Genkai_wpf
{
public class CustomClass
{
public UNITY_DB_PRODEntities12 Genkai_db = new UNITY_DB_PRODEntities12();
public static string[] probtpRegex;
public static string[] audiensRegex;
public static string OUDestructionProbtp;
public static string OUDestructionAudiens;
public void Init()
{
OUDestructionProbtp = Genkai_db.Config.First(x => x.Properties == "OUDestructionProbtp").Value;
OUDestructionAudiens = Genkai_db.Config.First(x => x.Properties == "OUDestructionAudiens").Value;
probtpRegex = Genkai_db.Config.First(x => x.Properties == "Regex_Probtp").Value.Split(',');
audiensRegex = Genkai_db.Config.First(x => x.Properties == "Regex_Audiens").Value.Split(',');
}
}
this code work find in code and retrieve some regex stored in my db config table.
but in unittest I can't test this ini method because EF refuse with random error on all my different tries.
here shunk of code in my unitTest.cs
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
private TestContext testContextInstance;
CustomClass PROBTP = new CustomClass();
public UnitTest1()
{
PROBTP.Init();
}
}
}
I call the CustomClass.init() method from public class UnitTest1 and get an error where it can't create an instance of my EF.
for better understanding try use my code in response thanks.
p.s.: I heard of mocking/effort/repository but I don't get it and don't even know what is really the best method...
the error in unitest : UNITY_DB_PRODEntities12 is the EF from main project in unitest name differente
<add name="UNITY_DB_PRODEntities1" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=M35824\MSQL32BIT;initial catalog=UNITY_DB_PROD;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
Nom du test : UT_Domain FullName de test : UnitTestProject1.UnitTest1.UT_Domain Source de test : c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\UnitTestProject1\UnitTest1.cs : ligne 48 Sortie du test : Échec Durée du test : 0:00:00
Message de résultat : Impossible de créer une instance de la classe UnitTestProject1.UnitTest1. Erreur : System.InvalidOperationException: La chaîne de connexion 'UNITY_DB_PRODEntities12' est introuvable dans le fichier de configuration de l'application..
StackTrace de résultat :
à System.Data.Entity.Internal.LazyInternalConnection.get_ConnectionHasModel()
à System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
à System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
à System.Data.Entity.Internal.Linq.InternalSet1.Initialize() à System.Data.Entity.Internal.Linq.InternalSet1.get_InternalContext()
à System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() à System.Linq.Queryable.First[TSource](IQueryable1 source, Expression`1 predicate)
à Genkai_wpf.CustomClass.Init() dans c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\Genkai_wpf\Control\CustomClass.cs:ligne 26
à UnitTestProject1.UnitTest1..ctor() dans c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\UnitTestProject1\UnitTest1.cs:ligne 27
I try then to give both connection string the same name but get an other error.
Nom du test : UT_Domain FullName de test : UnitTestProject1.UnitTest1.UT_Domain Source de test : c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\UnitTestProject1\UnitTest1.cs : ligne 48 Sortie du test : Échec Durée du test : 0:00:00
Message de résultat :
Impossible de créer une instance de la classe UnitTestProject1.UnitTest1. Erreur : System.Data.Entity.Core.MetadataException: Le schéma spécifié n'est pas valide. Erreurs :
Model1.csdl(3,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Autorisation' a déjà été défini.
Model1.csdl(10,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Config' a déjà été défini.
Model1.csdl(17,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.final_full_data' a déjà été défini.
Model1.csdl(58,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.final_McAfee' a déjà été défini.
Model1.csdl(71,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.final_probtp_user' a déjà été défini.
Model1.csdl(83,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Real_Time_Update' a déjà été défini.
Model1.csdl(89,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Stat_Transact' a déjà été défini.
Model1.csdl(98,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Synchronized_crossdomain_AD' a déjà été défini.
Model1.csdl(107,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Update_Status' a déjà été défini.
Model1.csdl(114,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.DCAI_ET' a déjà été défini.
Model1.csdl(124,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.debug_final' a déjà été défini.
Model1.csdl(134,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.debug_FPAC' a déjà été défini.
Model1.csdl(144,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.debug_McAfee' a déjà été défini.
Model1.csdl(154,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.final_bmc_fpac' a déjà été défini.
Model1.csdl(174,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Final_DCAI' a déjà été défini.
Model1.csdl(188,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.FPAC_Debug' a déjà été défini.
Model1.csdl(198,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Genkai_Delete' a déjà été défini.
Model1.csdl(214,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Temporary_BASEIP' a déjà été défini.
Model1.csdl(289,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Temporary_DCAI' a déjà été défini.
Model1.csdl(303,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Temporary_full_data' a déjà été défini.
Model1.csdl(554,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Check_Transact' a déjà été défini.
Model1.csdl(563,4) : erreur 0019: Chaque nom de type dans un schéma doit être unique. Le nom de type 'UNITY_DB_PRODModel.Record' a déjà été défini..
StackTrace de résultat :
à System.Data.Entity.Core.Metadata.Edm.EdmItemCollection.LoadItems(IEnumerable1 xmlReaders, IEnumerable1 sourceFilePaths, SchemaDataModelOption dataModelOption, DbProviderManifest providerManifest, ItemCollection itemCollection, Boolean throwOnError)
à System.Data.Entity.Core.Metadata.Edm.EdmItemCollection.Init(IEnumerable1 xmlReaders, IEnumerable1 filePaths, Boolean throwOnError)
à System.Data.Entity.Core.Metadata.Edm.MetadataCache.LoadEdmItemCollection(MetadataArtifactLoader loader)
à System.Data.Entity.Core.Metadata.Edm.MetadataCache.<>c__DisplayClass5.b__0(String k)
à System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory)
à System.Data.Entity.Core.Metadata.Edm.MetadataCache.GetMetadataWorkspace(String cacheKey, MetadataArtifactLoader artifactLoader)
à System.Data.Entity.Core.Metadata.Edm.MetadataCache.GetMetadataWorkspace(DbConnectionOptions effectiveConnectionOptions)
à System.Data.Entity.Core.EntityClient.EntityConnection.GetMetadataWorkspace()
à System.Data.Entity.Core.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection()
à System.Data.Entity.Core.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor, ObjectQueryExecutionPlanFactory objectQueryExecutionPlanFactory, Translator translator, ColumnMapFactory columnMapFactory)
à System.Data.Entity.Internal.InternalConnection.CreateObjectContextFromConnectionModel()
à System.Data.Entity.Internal.LazyInternalConnection.CreateObjectContextFromConnectionModel()
à System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
à System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
à System.Data.Entity.Internal.Linq.InternalSet1.Initialize() à System.Data.Entity.Internal.Linq.InternalSet1.get_InternalContext()
à System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() à System.Linq.Queryable.First[TSource](IQueryable1 source, Expression`1 predicate)
à Genkai_wpf.CustomClass.Init() dans c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\Genkai_wpf\Control\CustomClass.cs:ligne 26
à UnitTestProject1.UnitTest1..ctor() dans c:\Users\PB19150\Documents\£DOI-DIT-BIM\Developpement\DEV-C#\Genkai_Client_32\UnitTestProject1\UnitTest1.cs:ligne 27
both connection strings in both projects are in app.config. The first error say it can't find an instance of UNITY_DB_PRODEntities12 which makes sense since it's in the first project. in unittest name is different its UNITY_DB_PRODEntities1 not 12 the second error when I try give same name say that all my tables are duplicated.