单元测试气味
我正在尝试更改 ArcGIS 的单元测试,并开始使用模拟(我使用 rhino)。
当我开始编写测试时,我注意到我必须开始模拟很多对象,并存根很多方法,即使是单个测试也无法通过。
例如 - 我的控制器首先获取一个 RelationshipClass
(因此我需要存根 IWorkspace
和返回的 IRelationshipClass
),然后还获取一个 >IFeature
(存根),最后调用 stubRelClass.GetRelatedObjects(stubFeature)
,返回其他 IFeature
的 ISet
。
为了让它通过而必须存根这么多对象和方法是正常的吗? 我也感到 就像我真的需要跳过代码(是的 - 我知道我应该先编写测试,我仍在尝试这个),以便弄清楚下一步要存根什么,以及我应该返回什么。
我在模拟实现多个接口的 com 类时也遇到问题。 在生产代码中,我对它们之间的接口进行了 QI 处理。 如何创建一个在运行时实现这两个接口的模拟?
I am trying to change my unit testing of ArcGIS, and start using mocks (I use rhino).
When I started to get into writing the tests, I noticed I have to start mocking a lot of objects, and stub a lot of methods for even a single test to pass.
For example - my controller first gets a RelationshipClass
(so I need to stub the IWorkspace
and the returned IRelationshipClass
), then also gets an IFeature
(A stub), and finally calls stubRelClass.GetRelatedObjects(stubFeature)
, to return an ISet
of other IFeatures
.
Is it normal to have to stub so many objects and methods just to make it pass? I also feel
like I really need to step over the code (yeah - I know I should have written the tests first, I am still trying this one), in order to figure out what to stub out next, and what I should return.
I am also having problem with mocking com classes which implement more than one interface. In the production code I QI them between the interfaces. How can I create a mock that implements both interfaces at runtime?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,有时您必须模拟很多对象,具体取决于您的注入链。 如果您要深入多个级别,则可能表明存在设计错误 - 依赖于 API 下三层的数据的对象可能不是松散耦合的。 您应该能够通过在某个时刻返回某种具有您正在测试的层需要的必要属性的假对象来将链消灭在萌芽状态。
您还应该能够在
[SetUp]
方法中完成大部分模拟,然后让每个测试仅更改一两件事。为了模拟多个接口,Rhino 有 MultiMock 的概念。 我相信你所追求的语法是:
Depending on your injection chain, yes, sometimes you have to mock a lot of objects. If you're going multiple levels deep though, it may be indicative of a design fault - objects that are relying on data that is three layers down into your API may not be loosely coupled. You should be able to nip the chain in the bud by just returning a fake object of some kind at some point that has the necessary properties that the layer you're testing at needs.
You should also be able to do most of your mocking in a
[SetUp]
method and then have each test just change one or two things.For mocking multiple interfaces, Rhino has the concept of a MultiMock. I believe the syntax you're after is:
这可能是高耦合的标志 - 这反过来又意味着需要减少依赖性(这将提高设计和可测试性)。 作为粗略准则,一个对象最多应有 4-6 个协作者。 任何超出这个范围的事情都会引起我的警报。
如何使用 Mock?
It might be a sign of high coupling - which in turn implies a need to reduce dependencies (which will improve design and testability). As a rough guideline, an object should have around 4-6 collaborators max. Anything over that would set off my alarms.
How are Mocks meant to be used?
对我来说,这听起来像是无法测试的代码,这是一种味道:-(
我建议阅读 http: //misko.hevery.com/code-reviewers-guide/。作者是负责测试领域的 Google 开发人员的教练,他在文章中展示了如何编写可测试和不可测试的代码
。 :
Clean Code (Robert C. Martin) - 主要关注如何编写干净的(对应于可测试的)代码。
有效地处理遗留代码 (Michael Feather) - 展示了控制未经测试和不可测试的代码的方法。
To me it sounds like untestable code, which is a smell :-(
I would recommend reading http://misko.hevery.com/code-reviewers-guide/. The author is coach responsible for teaching google developers in the testing area. In the article he shows how you can write testable and untestable code.
Further recommended reading:
Clean Code (Robert C. Martin) - main focus on how to write clean (which corresponds to testable) code.
Working effectively with legacy code (Michael Feather) - shows ways to get untested and untestable code under control.