【问题标题】:Unit Testing Unit of Work and Generic Repository Pattern framework using Moq使用 Moq 的单元测试工作单元和通用存储库模式框架
【发布时间】:2016-03-14 19:52:35
【问题描述】:

我正在对使用 Moq 的工作单元和通用存储库的服务进行单元测试。问题是在服务类中,当我在调试模式下运行测试时,_subsiteRepository 始终为空。

我正在模拟的服务类的设置

private readonly IRepository<Subsite> _subsiteRepository;

public PlatformService(IUnitOfWork<PlatformContext> unitOfWork)
{
    _subsiteRepository = unitOfWork.GetRepository<Subsite>();
}

以及正在测试的此类中的方法。问题是 _subsiteRepository 始终为空。该方法的作用不止于此,但这是相关部分。

public async Task<IEnumerable<Subsite>> GetSubsites()
{
    // Get Subsites
    var subsites = await _subsiteRepository
        .GetAll()
        .ToListAsync();
}

最后这是我正在运行的测试:

private readonly Mock<IRepository<Subsite>> _subsiteRepository;
private readonly Mock<IUnitOfWork<PlatformContext>> _unitOfWork;
private readonly PlatformService _platformService;

_subsiteRepository = new Mock<IRepository<Subsite>>();
_unitOfWork = new Mock<IUnitOfWork<PlatformContext>>();
_platformService = new PlatformService(_unitOfWork.Object);

// Arrange
var fakeSubsites = new List<Subsite>
{
    new Subsite {IDSubsite = new Guid(), Title = "Subsite One"}
}.AsQueryable();

_unitOfWork.Setup(x => x.GetRepository<Subsite>()).Returns(_subsiteRepository.Object);
_unitOfWork.Setup(x => x.GetRepository<Subsite>().GetAll()).Returns(fakeSubsites);

// Act
var subsites = await _platformService.GetSubsites(null, null);

// Assert
Assert.NotNull(subsites);

【问题讨论】:

  • 在创建PlatformService 之后设置unitOfWork.GetRepository。因此,您永远不会在PlatformService 的构造函数中真正获得subsiteRepository.Object。我会在您需要调用对象之前移动PlatformService 的构造,即在Act 之前。
  • 不完全相关,但你有什么理由不只是Mock&lt;ISubsite&gt; 我假设存储库有一个接口

标签: c# unit-testing moq


【解决方案1】:

在 Arrange 步骤之后移动创建 _platformService。因为您在设置 unitOfWork 模拟之前调用了 PlatformService 构造函数。

_subsiteRepository = new Mock<IRepository<Subsite>>();
_unitOfWork = new Mock<IUnitOfWork<PlatformContext>>();

// Arrange
var fakeSubsites = new List<Subsite>
{
    new Subsite {IDSubsite = new Guid(), Title = "Subsite One"}
}.AsQueryable();

_unitOfWork.Setup(x => x.GetRepository<Subsite>()).Returns(_subsiteRepository.Object);
_unitOfWork.Setup(x => x.GetRepository<Subsite>().GetAll()).Returns(fakeSubsites);

// Act
_platformService = new PlatformService(_unitOfWork.Object);
var subsites = await _platformService.GetSubsites(null, null);

// Assert
Assert.NotNull(subsites);

【讨论】:

  • 我完全同意你回答的第一部分,但我不同意你的第二部分。是的,他们试图一次测试两个不同的部分,但单元测试不应该直接影响您的代码,因此您不需要添加到您的业务逻辑中仅用于测试。我建议他们考虑一种简单地提供Subsite 而不是使用IUnitOfWork&lt;T&gt; 作为服务定位器反模式的方法,因此涵盖了消除对模拟IUnitOfWork&lt;T&gt; 的依赖的第二点
  • @StephenRoss 我删除了第二部分,因为我认为它是基于意见的,它没有为用户提出的问题提供答案。感谢您的评论。
  • 谢谢!我从根本上误解了起订量是如何工作的。也感谢 cmets 拆分单元测试。我一定会研究如何将它干净地分开并一次测试一件事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多