2011-12-05 48 views
0

我有一个项目,我在其中使用.nettiers生成的代码作为我的DAL。Mocking .nettiers DataRepository调用

目前,我的测试包括物理设置每个测试数据库中的测试数据,然后允许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个类别对于我能够在单元测试中整合通用代码很有帮助。测试驱动的开发支持者可能会说,努力生成一套干净的单元测试代码是应用程序中的设计缺陷的一个指示。我不会不同意这一点,但不幸的是,我所参与的项目通常没有提供简单且全面的单元测试代码库。简单的单元测试通常不会真正探究有问题的场景,而综合单元测试通常需要大量的测试设置逻辑。

+0

我正在测试InterfaceManagerService,所以看起来我需要模拟DataRepository(提供者是它的属性)。但是,NetReader DataRepository没有与之关联的接口,所以我不确定如何将DI引入服务类。 – Steve

+0

@Steve无论您想要处理这个麻烦,这都取决于您,但您可以定义自己的接口以及自己的包装类,以实现实现该接口的nettiers DataRepository。 InterfaceManagerService可以使用您的接口,从而允许您将不同的(即模拟)实现替换为InterfaceManagerService类。 –

+0

@Steve尽管如此,您仍然面临着是否测试新包装类的问题。在某些时候,您可能需要为代码定义一个截止点,以便使用自动单元测试进行测试。如果你的InterfaceManagerService已经基本上是nettiers DataRepository的包装器(也就是说,如果这只是它的话),那么为nettiers DataRepository类创建一个新的包装器类可能没有什么好处。对不起,我觉得我对你的问题没什么帮助。 –

0

我使用TypeMock,我非常喜欢它。嘲笑一个班的内部真的很容易。我想要做的是覆盖DataRepository类,并让TypeMock将预期的结果集返回给正在使用它的组件,以确保该组件按预期工作。

但实际上,这取决于您正在测试的内容。如果您正在测试服务,则伪造数据存储库并返回预期结果。如果您正在测试存储库,那么伪造存储库消耗的内部部件。所以一个好主意是伪造你正在测试的组件的外部引用,恕我直言。

HTH。