我有一个项目,我在其中使用.nettiers生成的代码作为我的DAL。
目前,我的测试包括在数据库中为每个测试物理设置测试数据,然后允许nettiers对象访问数据库并根据需要返回。
显然,这不是特别有效,到目前为止我的250多个测试需要大约10分钟才能运行,所以我一直在考虑在我的测试中加入模拟。
虽然我非常确定我理解模拟数据库调用的概念,但我特别难以将其应用于nettiers,因为它与数据库相当紧密耦合。
我想测试的其中一种方法看起来像这样(为了简洁起见,略微减少):
public class InterfaceManagerService
{
public DataDocument SaveDataDocument(DataDocument entity)
{
var lookupEntity = DataRepository.DataDocumentProvider.GetByDocumentId(entity.DocumentId);
if (lookupEntity == null)
{
File fileEntity = new File();
fileEntity.Name = entity.Name;
var savedFileEntity = DataRepository.FileProvider.Save(fileEntity);
entity.FileId = savedFileEntity.FileId;
var savedEntity = DataRepository.DataDocumentProvider.Save(entity);
return (savedEntity);
}
}
}
目前,我正在使用Typemock的试用版,因为它似乎可以满足要求,但我愿意接受任何替代方案,特别是开源软件。
我遇到的第一个问题是,我是否应该创建一个模拟的InterfaceManagerService实例,或DataRepository,或实体本身(nettiers实体确实有一个可能有用的接口)。
第二个问题是,如何创建要返回的虚假对象,因为nettiers将一堆额外的属性放入实体中,如果我创建每个对象的虚假实例,那将导致大量且难以进行的测试我期待着。
我想最终,我正在寻找一些方法,以最好的方式为使用nettiers数据存储库方法的方法编写单元测试,但是为了避免命中数据库,因为它似乎没有多少关于它互联网目前。
答案 0 :(得分:3)
我将根据我的个人经验提出一些建议。虽然这些可能无法解决您的所有问题,但我希望它们至少对您有所帮助。
Rhino Mocks是一个相当着名的模拟框架。如果您正在寻找Typemock的替代方案,我建议您这样做。
关于是否要模拟InterfaceManagerService或DataRepository,我会说这取决于你要测试的内容。你想测试InterfaceManagerService吗?然后,您需要为DataRepository.FileProvider和DataRepository.DataDocumentProvider创建模拟对象。如果您还不熟悉“依赖注入”的概念,那么请研究一下;看起来你应该对你的InterfaceManagerService类应用一些依赖注入(假设你想对它进行单元测试)。
如果您想要使用InterfaceManagerService的单元测试代码,那么只需模拟InterfaceManagerService。
...如何创建要返回的虚假对象,因为nettiers 将一堆额外的属性放入将导致的实体中 如果我创建了每个的假实例,那么在大而且不成熟的测试中 我期待的对象。
编写单个单元测试很容易。编写许多单元测试以涵盖您需要涵盖的所有场景,并且以有效的方式执行此操作,这不会导致在整个单元测试中复制很多代码很困难,尤其是在测试方法的输入和输出时很复杂。
对于这个我没有太多的指导,除了说我的个人方法是尝试整合测试初始化逻辑和测试验证逻辑,以避免大量的代码重复,但同时我尝试避免使单元测试代码本身如此复杂以至于难以理解并容易出现错误。
总的来说,我认为我最终将测试逻辑分为3类:输入/初始化,期望和结果/验证。我发现将逻辑放入这3个类别对于我能够在单元测试中整合公共代码是有帮助的。
顽固的测试驱动开发支持者可能会说,努力生成一套干净的单元测试代码表明应用程序存在设计缺陷。我不会不同意这一点,但我会说,不幸的是,我参与过的项目通常没有产生一个既简单又全面的单元测试代码库。简单的单元测试通常没有真正探索有问题的场景,而全面的单元测试通常需要大量的测试设置逻辑。
答案 1 :(得分:0)
我使用TypeMock,我非常喜欢它。模拟一个类的内部非常容易。我要做的是覆盖DataRepository类,让TypeMock将预期的结果集返回给正在使用它的组件,以确保组件按预期工作。
但实际上,这取决于你在测试什么。如果您正在测试该服务,请伪造数据存储库并返回预期结果。如果您正在测试存储库,那么伪造存储库使用的内部。所以一个好主意就是伪造你正在测试的组件的外部引用,恕我直言。
HTH。