2012-09-21 26 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)的普通接口作爲映射器的源代碼。