单位测试气味

时间:2009-06-29 06:18:58

标签: unit-testing mocking rhino-mocks arcgis

我正在尝试更改ArcGIS的单元测试,并开始使用模拟(我使用rhino) 当我开始编写测试时,我注意到我必须开始模拟很多对象,并且存在很多方法,甚至可以通过单个测试。
例如 - 我的控制器首先获得RelationshipClass(所以我需要存根IWorkspace和返回的IRelationshipClass),然后获得IFeature(存根),并且最后拨打stubRelClass.GetRelatedObjects(stubFeature),返回ISet其他IFeatures

为了让它通过,必须存根这么多的对象和方法是否正常?我也感到 就像我真的需要跨过代码一样(是的 - 我知道我应该首先编写测试,我还在尝试这个),以便弄清楚接下来会发生什么,以及我应该返回什么。

我也遇到了模拟实现多个接口的com类的问题。在生产代码I QI他们之间的接口。如何创建一个在运行时实现两个接口的模拟器?

3 个答案:

答案 0 :(得分:3)

根据您的注射链,是的,有时您必须模拟许多对象。如果你的目标深入多层次,则可能表明设计存在缺陷 - 依赖于三层数据的对象可能不会松散耦合。你应该能够通过在某个点上返回某种虚假对象来扼杀链条,这些对象具有您正在测试的层所需的必要属性。

您还应该能够使用[SetUp]方法完成大部分模拟操作,然后让每个测试只更改一两件事。

对于模拟多个接口,Rhino具有MultiMock的概念。我相信你所遵循的语法是:

var mock = 
    MockRepository.DynamicMultiMock<MyType>(
              typeof(Interface1), 
              typeof(Interface2), 
              ....);

答案 1 :(得分:3)

这可能是高耦合的标志 - 这反过来意味着需要减少依赖性(这将改善设计和可测试性)。作为一个粗略的准则,一个对象最多应该有4-6个合作者。任何事情都会引发我的警报。

How are Mocks meant to be used?

答案 2 :(得分:2)

对我而言,它听起来像不可测试的代码,这是一种气味:-(

我建议阅读http://misko.hevery.com/code-reviewers-guide/。作者是教练,负责在测试领域教授谷歌开发人员。在文章中,他展示了如何编写可测试和不可测试的代码。

进一步推荐阅读: 清洁代码(Robert C. Martin) - 主要关注如何编写干净(对应于可测试的)代码。 使用遗留代码(Michael Feather)有效地工作 - 显示了控制未经测试和不可测试代码的方法。