当服务传递给基类的泛型方法时,不会调用Moq'ed服务方法
本文关键字:服务 Moq 调用 方法 ed 基类 泛型方法 | 更新日期: 2023-09-27 17:54:39
我有一个管理列表项的基类的泛型方法:
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; }
}
您的问题描述如下:
我的测试没有通过,当我遍历调用的代码时service.GetById (id);在我的基类中返回null
所以一定是对ManageListItems<TE>()
的调用失败了:
var item = service.GetById(id);
希望我是正确的,因为这是一个假设[使用提供的信息]。
IMyListItemService
是否实现了IService<IEntity>
?因为你的代码暗示了它。
我能看到的唯一奇怪的是ManageListItems<TE>()
的最后一个参数期望一个类型为IService<TE> where TE is IEntity
的参数,该参数用于调用service.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});