如何包含关联实体

时间:2011-08-18 08:26:53

标签: unit-testing entity-framework-4 typemock-isolator

我想为下面的方法“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; 
 } 

以下是我的测试用例方法 -

[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); 
} 

在上面的测试用例方法中,我成功地通过电子邮件获取用户,但无法包含关联用户的其他实体。

请告诉我,如何将其他实体包含在关联用户中。

1 个答案:

答案 0 :(得分:2)

Include是漏洞抽象 - 它只适用于EF和linq-to-entities,并且不能成功地与linq-to-objects一起使用。您知道您的单元测试需要填充关系,因此您的GetUsers方法必须准备该数据。这是嘲弄/伪造的一点 - 你不会考虑模拟方法的内部实现。您只需返回应返回的内容。

顺便说一下。你的考试有什么意义?看起来你正试图测试一个模拟 - 这是错误的。 Mock提供了正确的数据,您只需要它来测试另一个依赖于模拟组件的功能。