1

リスト項目を管理するための基本クラスにジェネリック メソッドがあります。

public abstract class BaseViewModelHandler<T> : BaseLogger, IViewModelHandler<T>
    where T : IViewModel
{
    public abstract void Handle(T viewModel);

    protected ISet<TE> ManageListItems<TE>(int[] selectedItemIds, ISet<TE> list, IService<TE> service)
        where TE : IEntity
    {
        try
        {

... param checking and code to remove unwanted items not included for brevity

            if (selectedItemIds.Any())
            {
                var itemIdsToAdd = selectedItemIds.Where(id => list.All(x => x.Id != id)).ToList();
                if (itemIdsToAdd.Any())
                {
                    foreach (var id in itemIdsToAdd)
                    {
                        var item = service.GetById(id);
                        list.Add(item);
                    }
                }
            }

            return list;
        }

...catch block removed for brevity

    }
}

この基本クラスを継承するクラスがあります。

public class ConcreteViewModelHandler : BaseViewModelHandler<ConcreteViewModel>
{
    private readonly IMyService _myService;
    private readonly IMyListItemsService _myListItemsService

    public ConcreteViewModelHandler (IMyService myService, IMyListItemsService myListItemsService)
    {
        _myService = myService;
        _myListItemsService = myListItemsService
    }

    public override void Handle(ConcreteViewModel viewModel)
    {
        try
        {
            var myEntity = viewModel.Id.HasValue
                               ? _myService.GetById(viewModel.Id.Value)
                               : new MyEntity();

            myEntity.ListToManage = ManageListItems(viewModel.SelectedItemIds, myEntity.ListToManage, _myListItemsService);

...create/update removed for brevity

        }

...catch block removed for brevity

    }
}

Handle メソッドをテストしようとしています。私のテストでは、サービスをモックし、「GetById」メソッドをセットアップして、クラスの新しいインスタンスを返します

_myListItemsServiceMock = new Mock<IMyListItemsService>();
_myListItemsServiceMock
      .Setup(s => s.GetById(It.IsAny<int>()))
      .Returns(new MyListItem{ Id : 1});

コードをステップ実行すると、基本クラスでの呼び出しservice.GetById(id); が null を返します。これは私が Moq を適切に使用した最初のプロジェクトなので、フレームワークの経験が浅いために何かが足りないのではないかと心配しています。

どんな助けでも大歓迎です。

要求に応じて TestFixture を追加します...

[TestFixture]
public class ConcreteViewModelHandlerTestFixture
{
    private Mock<IMyService> _myServiceMock;
    private Mock<IMyListItemsService> _myListItemsServiceMock;

    #region Test Data

    private readonly ConcreteViewModel _viewModel = new ConcreteViewModel
    {
        Id = 1,
    };

    #endregion

    [SetUp]
    public void SetUp()
    {
        _myServiceMock = new Mock<IMyService>();
        _myServiceMock
            .Setup(s => s.GetById(It.IsAny<int>()))
            .Returns(new MyEntity { Id: 1});

        _myListItemsServiceMock = new Mock<IMyListItemsService>();
        _myListItemsServiceMock
            .Setup(s => s.GetById(It.IsAny<int>()))
            .Returns(new MyListItem{ Id : 1});
    }


    [Test]
    public void _the_handle_method_works()
    {
        //arrange
        var handler = new ConcreteViewModelHandler(_myServiceMock.Object, _myListItemsServiceMock.Object);

        // act
        handler.Handle(_viewModel);

        // assert
        // no assertions yet as the code falls over
    }
}

@Quinton Bernhardt のリクエストに応じて詳細を追加

インターフェース:

public interface IEntity
{
    int Id { get; }
    //Guid Guid { get; }
    int UpdateId { get; set; }
}

基本クラス:

public abstract class BaseEntity : IEntity
{
    protected BaseEntity()
    {
    }

    protected BaseEntity(int id)
    {
        Id = id;
    }

    public virtual int Id { get; protected internal set; }
    public virtual int UpdateId { get; set; }
}

および MyListItem クラス

public class MyLIstitem : BaseEntity
{
    public MyLIstitem ()
    {
    }

    public MyLIstitem (int id)
        : base(id)
    {
    }


    public virtual string Name { get; set; }
    public virtual string Value { get; set; }
}
4

1 に答える 1

1

問題の説明は次のように述べています。

service.GetById(id); への呼び出しのコードをステップ実行すると、テストに合格しません。私の基本クラスでは null を返します。

ManageListItems<TE>()したがって、回線で失敗するのはへの呼び出しである必要があります。

var item = service.GetById(id);

[提供された情報を使用して] 仮定であるため、正しいことを願っています。

IMyListItemService実装しIService<IEntity>ますか? あなたのコードはそれを暗示しています。

私が見ることができる唯一の奇妙な点は、の最後のパラメーターが、への呼び出しに使用されるManageListItems<TE>()タイプのパラメーターを期待していることです。IService<TE> where TE is IEntityservice.GetById(id)

protected ISet<TE> ManageListItems<TE>(int[] selectedItemIds, ISet<TE> list, IService<TE> service)

私と一緒にいてください...、それは後で意味があります...

ただし、具体的なクラスからそのメソッドに提供するオブジェクトは、次のメソッドIMyListItemsServiceからわかるように型です。Handle

myEntity.ListToManage = ManageListItems(viewModel.SelectedItemIds, myEntity.ListToManage, _myListItemsService);

何が起こっていると思います...のセットアップはGetById、のIService代わりにIMyListItemsService

リスト サービスで GetById を設定する場合は、次の代わりに:

    _myListItemsServiceMock
        .Setup(s => s.GetById(It.IsAny<int>()))
        .Returns(new IMyListItem{ Id : 1});

試す

    _myListItemsServiceMock.As<IService>()
        .Setup(s => s.GetById(It.IsAny<int>()))
        .Returns(new IMyListItem{ Id : 1});

また

    _myListItemsServiceMock.As<IService<IEntity>>()
        .Setup(s => s.GetById(It.IsAny<int>()))
        .Returns(new IMyListItem{ Id : 1});
于 2013-01-20T08:59:23.583 に答える