0
Answer

Mock Database with ID column

Paul Simpson

Paul Simpson

8y
351
1

I'm (fairly) new to TDD, so be gentle!

I am using CodeFirst to create my application in C# using EF6 in VBS2015 Community.

I have an Interface created for my data access and am able to create a Mock Database in memory for Unit testing.

Each of my Models has a unique identifier column which is named Id (For example, UserID)

Ok, so when I add records to my Mock database, I need to have it create a new ID value for the record, as I reference this in later code. How do I do this with a generic set, when each table has a unique ID column? Do I have to mock out each table independently?

My database interface looks like this:

  1. Namespace Labinator2016.Lib.Headers  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.Linq;  
  6.     public interface ILabinatorDb : IDisposable  
  7.     {  
  8.         IQueryable<T> Query<T>() where T : class;  
  9.         void Add<T>(T entity) where T : class;  
  10.         void Delete<T1>(System.Linq.Expressions.Expression<Func<T1, bool>> target) where T1 : class;  
  11.         void Remove<T>(T entity) where T : class;  
  12.         void Update<T>(T entity) where T : class;  
  13.         void SaveChanges();  
  14.     }  
  15. }   

My Mock Database then looks like this:

  1. namespace Labinator2016.Tests.TestData  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.Linq;  
  6.     using Lib.Headers;  
  7.     using Labinator2016.Lib.Models;  
  8.     class FakeDatabase : ILabinatorDb  
  9.     {  
  10.         public IQueryable<T> Query<T>() where T : class  
  11.         {  
  12.             return this.Sets[typeof(T)] as IQueryable<T>;  
  13.         }  
  14.         public void Dispose() { }  
  15.         public void AddSet<T>(IQueryable<T> objects)  
  16.         {  
  17.             this.Sets.Add(typeof(T), objects);  
  18.         }  
  19.         public void Add<T>(T entity) where T : class  
  20.         {  
  21.             this.Added.Add(entity);  
  22.             IQueryable<T> temp = this.Sets[typeof(T)] as IQueryable<T>;  
  23.             List<T> existing = temp.ToList();  
  24.             existing.Add(entity);  
  25.             Sets[typeof(T)] = existing;  
  26.         }  
  27.         void ILabinatorDb.Delete<T1>(System.Linq.Expressions.Expression<Func<T1, bool>> Target)  
  28.         {  
  29.         }  
  30.         public void Update<T>(T entity) where T : class  
  31.         {  
  32.             this.Updated.Add(entity);  
  33.         }  
  34.         public void Remove<T>(T entity) where T : class  
  35.         {  
  36.             this.Removed.Add(entity);  
  37.         }  
  38.         public void SaveChanges()  
  39.         {  
  40.             this.saved++;  
  41.         }  
  42.         public Dictionary<Type, object> Sets = new Dictionary<Type, object>();  
  43.         public List<object> Added = new List<object>();  
  44.         public List<object> Updated = new List<object>();  
  45.         public List<object> Removed = new List<object>();  
  46.         public int saved = 0;  
  47.     }  
  48. }  
 
Currently, I have some code that gets a user object from a user table, based on a name. If it doesn't exist, then one is created first. Here is my code:
  1. User existingUser = this.db.Query<User>().Where(u => u.UserName == newUserName).FirstOrDefault();  
  2. if (existingUser == null)  
  3. {  
  4.     User userToAdd = new User();  
  5.     userToAdd.UserName = newUserName;  
  6.     userToAdd.Password = PasswordHash.CreateHash("password");  
  7.     this.db.Add<User>(userToAdd);  
  8.     this.db.SaveChanges();  
  9.     existingUser = this.db.Query<User>().Where(u => u.EmailAddress == nu).FirstOrDefault();  
  10. }  
 
So, am I using the wrong approach completely in my application, or is there a way to mock out this functionality?