1

我正在尝试测试我的一项名为 GetUsersForRole 的服务。它接受一个简单的字符串并将其传递给我的 RoleRepository 以处理 NHibernate 并获取一个角色集合,其中包含为其 RoleName 传入的字符串。为此,我的 RoleRepository 上有一个 Find 函数,它调用此代码:

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 的属性,称为 Users。如果给定的角色绑定了用户(通过多对多),则填充此属性。

从这里开始,我处理这个 Find 函数的结果并获得第一个角色,然后我使用 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;

我正在使用 value Injector 的 Automapper Simulation 类来处理集合映射。这可以在这里找到。我必须制作一个特殊的 Mapper 来处理 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 会话实例,我将无法使用 NHibernate.Collection.PersistantSet 键入我的模拟。有没有人对这里发生的事情以及我如何能够在我的模拟数据安排中复制 NHibernate 对我的 Iesi.Collections.ISet 所做的事情有任何想法?

4

1 回答 1

0

如果我理解你是正确的,你ISet<T>的域模型中有一个吗?为什么不在映射器中使用它作为源?为什么是非泛型接口?

另一种选择是,您有一个通用接口和非通用接口(如 IEnumerable)作为映射器中的源。

于 2012-09-21T22:40:23.257 回答