2012-09-21 91 views
1

我试图测试一个名为GetUsersForRole的我的服务。它接受一个简单的字符串,并将其传递给我的RoleRepository来处理NHibernate,并通过为其RoleName传入的字符串获取一个Roles集合。要做到这一点,我有一个调用此代码对我RoleRepository查找功能:NHibernate对我的Iesi.Collections.ISet做了什么?

ICriteria crit = rb.unitOfWork.Session.CreateCriteria(typeof(Entity)); 
crit.SetCacheable(false); 
foreach (object[] criteriaItem in criteria) 
{ 
    crit.Add(Expression.Eq((string)criteriaItem[0], criteriaItem[1])); 
} 

return crit.List().Cast<Entity>(); 

所以上面的代码将返回的角色和范围内的一个列表,有一个定义为Iesi.Collections.ISet一个属性调用用户。如果一个给定的角色与用户绑定(通过多对多),则此属性将被填充。

从这里开始,我处理Find函数的结果并获取第一个Role,然后使用ValueInjector将role.Users属性映射到IEnumerable集合。这工作100%。这是这样的代码:

var role = _roleRepo.Find(new List<object[]>() 
           { 
            new object[] {"Name", roleName} 
           }).FirstOrDefault(); 

if (role == null) 
    return null; 

MapperFactory.ClearMappers(); 
MapperFactory.AddMapper(new ISetToIEnumerable<User, UserDTO>()); 

var users = Mapper.Map<Iesi.Collections.ISet, IEnumerable<UserDTO>>(role.Users); 

return users; 

我使用值注入器的Automapper模拟类来处理集合映射。这可以找到here。我不得不做出一个特殊的映射与Iesi.Collections.ISet工作IEnumerable的映射:

public class ISetToIEnumerable<TSource, TTarget> : TypeMapper<Iesi.Collections.ISet, IEnumerable<TTarget>> 
{ 
    public override IEnumerable<TTarget> Map(Iesi.Collections.ISet source, IEnumerable<TTarget> target) 
    { 
     base.Map(source, target); 

     List<TTarget> entities = new List<TTarget>(); 
     foreach (var entity in source) 
     { 
      entities.Add(Mapper.Map<TSource, TTarget>((TSource)entity)); 
     } 
     target = entities.AsEnumerable(); 
     return target; 
    } 
} 

同样,该工程100%。在ISetToIEnumerable映射器类中,参数源以Iesi.Collections.ISet {NHibernate.Collection.PersistantSet}形式出现。这是在尝试单元测试时遇到的问题。

我试图测试这个单元测试运行成功:

[Test] 
    public void GetUsersForRole_success() 
    { 
     // Arrange 
     var roles = new List<Role>(); 
     var role = new Role() 
         { 
          Name = "role1", 
          Users = {new User() {Username = "user1"}, new User() {Username = "user2"}} 
         }; 
     roles.Add(role); 

     _mockRoleRepository.Setup(m => m.Find(It.IsAny<IList<object[]>>())).Returns(roles); 

     var service = GetDefaultService(); 

     // Act 
     var users = service.GetUsersForRole("role1"); 

     Assert.That(users.Count() == 2); 
    } 

当调试这一点,并步入service.GetUsersForRole(“role1上”)电话,我让我的嘲笑回来的数据从我的mockRoleRepository。这里的问题是,我的role.Users属性返回类型为Iesi.Collections.HashedSet(这是它如何在我的实体构造函数中实例化,用于NHibernate测试和实际运行)。现在,这成为我的ISetToIEnumerable类中的一个主要问题。我的源代码是Iesi.Collections.HashedSet。

我知道我将无法使用NHibernate.Collection.PersistantSet键入我的模拟,因为缺少NHibernate会话实例。有没有人对这里发生的事情有任何想法,以及我可以如何复制NHibernate对我的模拟数据安排中的Iesi.Collections.ISet所做的事情?

回答

0

如果我理解你的正确,你的域模型中有ISet<T>?你为什么不把它用作你的映射器的源代码?为什么非通用接口?

另一种替代方法是,您的泛型和非泛型接口(如IEnumerable)的普通接口作为映射器的源代码。