如何嘲笑实体经理
本文关键字:实体 何嘲笑 | 更新日期: 2023-09-27 17:59:44
我是单元测试的新手,刚刚开始为现有代码库编写单元测试。
我想为一个类的以下方法编写一个单元测试。
public int ProcessFileRowQueue()
{
var fileRowsToProcess = this.EdiEntityManager.GetFileRowEntitiesToProcess();
foreach (var fileRowEntity in fileRowsToProcess)
{
ProcessFileRow(fileRowEntity);
}
return fileRowsToProcess.Count;
}
问题出在GetFileRowEntitiesToProcess();
上。实体管理器是实体框架上下文的包装器。我对此进行了搜索,发现一个解决方案是使用已知状态的测试数据库进行测试。然而,在我看来,在测试代码中创建一些实体会产生更一致的测试结果。
但就其存在而言,如果不进行一些重构,我看不出有什么方法可以嘲笑Manager。
是否有解决此问题的最佳实践?我很抱歉这个问题有点天真,但我只想确保我在项目的其余部分走上正确的道路。
我在这里听到两个问题:
我应该嘲笑EdiEntityManager吗
是的。它是测试代码外部的依赖项,它的创建和行为是在代码外部定义的。因此,出于测试目的,应该注入一个具有已知行为的mock。
如何嘲笑EdiEntityManager
我们无法从发布的代码中得知。这取决于该类型是什么,它是如何创建并提供给包含对象的,等等。要回答这部分问题,你应该尝试:
- 为被调用的一个方法(
GetFileRowEntitiesToProcess()
)创建一个具有已知行为的mock - 将mock注入到正在测试的包含对象中
对于这两种努力中的任何一种,都要找出可能阻止这种情况发生的原因。每一个这样的发现要么涉及到对类型和mock的更多了解,要么将揭示重构的必要性以允许可测试性。发布的代码并没有透露这一点。
举个例子,假设EdiEntityManager
是在构造函数中创建的:
public SomeObject()
{
this.EdiEntityManager = new EntityManager();
}
这将是防止嘲笑的东西,因为它会妨碍上面的第2步。相反,构造函数将被重构为需要而不是实例化:
public SomeObject(EntityManager ediEntityManager)
{
this.EdiEntityManager = ediEntityManager;
}
这将允许测试提供mock,并且符合依赖反转原则。
或者EntityManager
是一个过于具体的类型,很难模拟/注入,那么实际的类型应该是EntityManager
定义的接口。这个问题最糟糕的情况可能是根本不控制类型,只需要定义一个包装器对象(它本身有一个可模拟的接口)来封装EntityManager
依赖项。