[翻译]编写可测试代码-谷歌测试小组博客
Writing Testable Code
http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html
Well there are no tricks to writing tests, there are only tricks to writing testable code.
1.将对象的创建和应用逻辑混淆在了一起2.xxx(SHOULD DO)3.在构造方法里做工作4.全局状态5.单例(披着羊皮的全局状态)6.静态方法(活在程序的世界)7.喜欢组合超过继承(SHOULD DO)8.喜欢多态胜过条件(SHOULD DO)9.混淆了服务对象和值对象10.混淆了条件
1.将对象的创建和应用逻辑混淆在了一起
- The factories, these are full of the "new" operators and are responsible for building the object graph of your application, but don't do anything.(只负责对象创建的工厂方法)
- And the application logic classes which are devoid of the "new" operator and are responsible for doing work. (负责处理逻辑)
- In test we want to test the application logic.
2.xxx(SHOULD DO)
- Just ask for all of the collaborators you need in your constructor.(在构造方法里得到所有的辅助对象)
- If you are a House class then in your constructor you will ask for the Kitchen, LivingRoom, and BedRoom, you will not call the "new" operator on those class
3.在构造方法里做工作
4.全局状态
- Global state is bad from theoretical, maintainability, and understandability point of view, but is tolerable at run-time as long as you have one instance of your application
5.单例(披着羊皮的全局状态)
- All of the internal objects of the singleton are global as well (and the internals of those objects are global as well... recursively)
6.静态方法(活在程序的世界)
- The key to testing is the presence of seams (places where you can divert the normal execution flow)
- Seams are essentially polymorphism (Polymorphism: at compile-time the method you are calling can not be determined).
- How much a static method will hurt from a testing point of view depends on where it is in you application call graph.
7.喜欢组合超过继承(SHOULD DO)
- Many developers use inheritance as code reuse which is wrong. Whether or not inheritance is appropriate depends on whether polymorphism is going on.
8.喜欢多态胜过条件(SHOULD DO)
- If you see a switch statement you should think polymorphisms. If you see the same if condition repeated in many places in your class you should again think polymorphism.
9.混淆了服务对象和值对象
- Value-objects, these tend to have lots of getters / setters and are very easy to construct are never mocked, and probably don't need an interface.
- Service-objects which do the interesting work, their constructors ask for lots of other objects for colaboration, are good candidates for mocking, tend to have an interface and tend to have multiple implementations
- A value-object should never take a service object in its constructor (since than it is not easy to construct).
- From a testing point of view we like value-objects since we can just create them on the fly and assert on their state. Service-objects are harder to test since their state is not clear and they are all about collaboration and as a result we are forced to use mocking, something which we want to minimize
10.混淆了条件
If summing up what the class does includes the word "and", or class would be challenging for new team members to read and quickly "get it", or class has fields that are only used in some methods, or class has static methods that only operate on parameters than you have a class which mixes concerns.