I have implemented a Repository Pattern using an onion Architecture and Entity Framework for Data Access, and now I want to test it using Moq. I just asked a question on SO and with the answer I am now more confused (the answer was good but I have very poor comprehension of how to mock even after reading doc). What I want to do is test Repository
method Get(long id)
. My repository constructor takes a DbContext
as parameter(called PrincipalServerContext
, so I was suggested to mock the context in order to test my Repository
. Let's say this is my Repository
:
public class PrincipalServerContext : DbContext
{
public DbSet<Web_Documents> WebDoc { get; set; }
public PrincipalServerContext()
: base("name=PrincipalServerDB")
{
Database.SetInitializer(new Initializer());
}
}
Now one of my POCOs Web_Documents
(EF entity):
public class Web_Documents
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long IDDocument { get; set; }
[Required]
[MaxLength(255)]
public string NomDocument { get; set; }
[Required]
public long IDCategorie { get; set; }
[ForeignKey("IDCategorie")]
public Web_Categories cat { get; set; }
[Required]
[MaxLength(255)]
public string Lien { get; set; }
[MaxLength(50)]
public string Type { get; set; }
public virtual ICollection<Web_Profils> Profils { get; set; }
}
And finally my Repository
method (knowing that repository is generic, I use POCOs as Generic Types):
public T Get(long id)
{
ObjectContext objContext = ((IObjectContextAdapter)context).ObjectContext;
ObjectSet<T> set = objContext.CreateObjectSet<T>();
IEnumerable<string> keyNames = set.EntitySet.ElementType
.KeyMembers
.Select(k => k.Name);
if (keyNames.Count() > 1)
return null;
else
{
string idName = keyNames.ElementAt(0); // For Document would be IDDocument
var parameter = Expression.Parameter(typeof(T));
var property = Expression.Property(parameter, idName);
var idValue = Expression.Constant(id, id.GetType());
var equal = Expression.Equal(property, idValue);
var predicate = Expression.Lambda<Func<T, bool>>(equal, parameter);
return entities.SingleOrDefault(predicate);
//Returns the corresponding entity to 'id' and 'T'
}
}
This builds an expression with appropriate ID names because every table has a different ID Name (company's policy).
From what I was told here Should this case of Assert.AreSame return true? I understand that I have to build a return type for the Mock object, but my context class is so thin I don't have any methods or anything, just a DbSet. So I tried this as a test but it probably makes no sense since it failed (I'm just really lost and don't understand it):
Mock<PrincipalServerContext> moqContext;
public void IdExists(){
moqContext = new Mock<PrincipalServerContext>();
var set = new Mock<DbSet<Web_Documents>>();
moqContext.Setup(c => c.Set<Web_Documents>()).Returns(set.Object);
repoDoc = new Repository<Web_Documents>(moqContext.Object);
var testDoc = repoDoc.Get(1L);
Assert.AreEqual(testDoc.NomDocument, "Ajouter une catégorie");
}
Say I would want to make a simple test to find if the ID searched corresponds to my DB entry, how should I set the moqContext
object I am trying to define? In examples I see they usually have methods for their mocked objects, but here none, so I found this Mocking DbContext for TDD Repository which made me try this test.
Thanks for your help!