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>();

したがって、上記のコードはロールのリストを返し、その中には、Users と呼ばれる 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 Simulation クラスを使用して、セット マッピングを処理しています。これはここにあります。Iesi.Collections.ISet から IEnumerable へのマッピングを操作するには、特別な Mapper を作成する必要がありました。

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 での実際の実行の両方で、Entity Constructor でインスタンス化される方法です)。これは私の ISetToIEnumerable クラスの大きな問題になります。私のソースは、Iesi.Collections.HashedSet として型付けされています。

NHibernate セッション インスタンスがないため、NHibernate.Collection.PersistantSet を使用してモックを入力できないことはわかっています。ここで何が起こっているのか、そしてモックデータのアレンジメントで NHibernate が Iesi.Collections.ISet に対して行っていることをどのように複製できるかについて、誰か考えがありますか?

4

1 に答える 1

0

あなたが正しいと理解できればISet<T>、あなたのドメインモデルには がありますか? これをマッパーのソースとして使用してみませんか? なぜ非ジェネリック インターフェイスなのですか?

もう 1 つの方法は、マッパーのソースとして IEnumerable のようなジェネリック インターフェイスと非ジェネリック インターフェイスの両方に一般的なインターフェイスを用意することです。

于 2012-09-21T22:40:23.257 に答える