1

I want to create test case for below method "GetByEmail".

 public User GetByEmail(string email, bool includeUserRoles = false, bool includeUserType = false)
 { 
    Expression<Func<User>> whereClause = u => u.Email == email; 

    return GetQuery(whereClause, includeUserRoles, includeUserType) .FirstOrDefault(); 
 } 

 private IQueryable<User> GetQuery(Expression<Func<User>> whereClause, 
                                   bool includeUserRoles = false, bool includeUserType = false) 
 { 
   IQueryable<User> query = base.GetQuery(whereClause); 

   if (includeUserRoles) 
     query = query.Include(u => u.UserRoles); 

   if (includeUserType) 
     query = query.Include(u => u.UserType); 

   return query; 
 } 

 protected IQueryable<T> GetQuery<T>(Expression<Func<T>> predicate) where T : EntityBase
 { 
    return predicate != null ? 
             CreateObjectSet<T>().Where(predicate) : 
             CreateObjectSet<T>(); 
 } 

 protected IObjectSet<T> CreateObjectSet<T>() where T : EntityBase 
 { 
   return _context.CreateObjectSet<T>(); 
 } 

 public static IQueryable<T> Include<T>(this IQueryable<T> source, Expression<Func<T>> property)
 { 
   var objectQuery = source as ObjectQuery<T>; 

   if (objectQuery != null) 
   { 
      var propertyPath = GetPropertyPath(property); 
      return objectQuery.Include(propertyPath); 
   } 

   return source; 
 } 

Below is my test case method -

[Fact] 
private void GetByEmail_PassedEmailAddress_RelatedUser() 
{ 
  //Created fake context 
  var fakeContext = Isolate.Fake.Instance<Entities>(); 

  //Created fake Repository and passed fakeContext to it 
  var fakeRepository = Isolate.Fake.Instance<Repository>(Members.CallOriginal,   ConstructorWillBe.Called, fakeContext);

  //Created fake in memory collection of User 
  var fakeUsers = GetUsers(); 

  Isolate.WhenCalled(() => fakeContext.Context.CreateObjectSet<User>()) 
         .WillReturnCollectionValuesOf(fakeUsers); 

  var User = Isolate.Invoke.Method(fakeRepository, "GetByEmail", "abc@xyz.com", true, true);

  Assert.True(User != null); 
} 

In the above test case method I successfully get the user with passed email but not able to include other entities of associated user.

Kindly let me know, how can I include other entities with associated User.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
Yogesh
  • 829
  • 2
  • 8
  • 21

1 Answers1

2

Include is leaky abstraction - it works only with EF and linq-to-entities and cannot be successfully used with linq-to-objects. You know that your unit test needs populated relations so your GetUsers method must prepare that data. That is a point of mocking / faking - you don't think about internal implementation of mocked method. You simply return what should be returned.

Btw. what is the point of your test? It looks like you are trying to test a mock - that is wrong. Mock provides correct data and you only need it to test another feature dependent on mocked component.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • I am returning IQueryable as User. Should I have to return something else instead of Iqueryable. private IQueryable GetUsers() { var list = new List { new User() {UserID=1,FirstName="abc",LastName="xyz",UserEmail="abc@xyz.com"}, new User(){UserID=2,FirstName="lmn", LastName="ijk",UserEmail="lmn@ijk.com"}, new User(){UserID=3,FirstName="pqr",LastName="stu",UserEmail="pqr@stu"}, }; return list.AsQueryable(); } – Yogesh Aug 18 '11 at 09:05
  • Returning IQueryable make your repository hardly mockable and your dependent code hardly unit testable. I wrote multiple post about this problem. Check it [here](http://stackoverflow.com/questions/6766478/unit-testing-dbcontext) or [here](http://stackoverflow.com/questions/6904139/fake-dbcontext-of-entity-framework-4-1-to-test). `IQueryable` is way to develop applications with EF but it is currently probably impossible to ensure that your unit tests on mocked `IQueryable` will test your real application. My usual recommendation is either hide `IQueryable` or use integration tests with real DB. – Ladislav Mrnka Aug 18 '11 at 09:26