Java

Spring的集成测试测什么?

spring reference的原文:     *The correct wiring of your Spring IoC container contexts.     * Data access using JDBC or an ORM tool. This would include such things as the correctness of SQL statements, Hibernate queries, JPA entity mappings, etc.

Service层的单元测试:与其Mock别人,不如Mock自己

此为抛砖贴,希望能引出更好的见解。 你会怎么单元测试这样一个service层的类? public class Service { private BizOne bizOne; private BizTwo bizTwo; public boolean doBiz(Object param) { Object resultOne = bizOne.getIt(param); if (resultOne == null) { return false; } return bizTwo.getIt(param) == null; } … } 不管怎么测,对bizOne和bizTwo的调用都得mock掉,否则你的测试类可能会直接访问数据库或者依赖容器。所以你可能会这样写测试代码: // do mocking BizOne bizOne = expectBizOneNotReturnNull(param); BizTwo bizTwo = expectBizTwoReturnNull(param); // inject mocked objects service.setBizOne(bizOne); service.setBizTwo(bizTwo); assertTrue(service.doBiz(param)); …

Service层的单元测试:与其Mock别人,不如Mock自己 Read More »

Service层的单元测试:在测试方法单元性和所需Mock的次数上取得平衡

都说单元测试应该喵准单个方法,每个测试方法只测一小部分逻辑。 但另一方面,如果测试时总是要Mock,你就要想办法少Mock一些东西,因为Mock代码写起来是很累、很难看的 Service层的代码往往就是这种情况。看个例子: 你会怎么测下面这样的代码: //仔细看下,这是一棵4层的判定树 public class Service { //为了层次清晰,没有使用驼峰式命名 public boolean do_biz() { if (!is_biz_one_valid()) { return false; } return is_biz_two_valid(); } boolean is_biz_two_valid() { if (!is_two_a_valid()) { return false; } return is_two_b_valid(); } boolean is_two_b_valid() { if (!is_two_b_left_valid()) { return false; } return is_two_b_right_valid(); } … 本着每个测试方法只测一小块逻辑的原则,你可能会这样写: @Test public void test_do_biz() { Service …

Service层的单元测试:在测试方法单元性和所需Mock的次数上取得平衡 Read More »

Lobo: Java Web Browser

Lobo 是一款用java写的开源浏览器 有时间可以读读它的源码,可以帮助你学习http规范 http://lobobrowser.org/java-browser.jsp

GBK里的字符在UNICODE里都有吗?

答案:是的。 一开始有些字在Unicode里没有,后来Unicode版本升级后把它们加进去了。 见wikipedia: 事实上比较起来, GBK 定义之字符较 CP936 多出95字(15个非汉字及80个汉字),皆为其时未收入 ISO 10646 / Unicode 之符号:非汉字包括异体字符号[2]、十二个表意文字描述字符(Ideographic Description Characters)[3]及 GB 5007.1-85《信息交换用汉字 24×24 点阵字模集》附录对 GB 2312 增加,但 Unicode 未收之拼音符号“ḿ”和“ǹ”[4][5];汉字包括未收入 ISO 10646 的《简化字总表》汉字52个、《康熙字典》及《辞海》汉字部件28个[4]。CP936中的这95字分配到了Unicode的私有区域[6][7],现已全部收于新版 Unicode。 [编辑]

ibatis: 能select出对象,但对象的每个属性都是null ?

这很有可能是因为:   1. 你的select statement没用resultMap,但用了resultClass   2. 而且你的select语句里没有使用 select coloumn_name as propertName 这种格式。 你可能省略了 as propertName 另外,使用 "select coloumn_name as propertName"属于取巧的做法;官方文档建议用resultMap: Using SQL aliases to map columns to properties saves defining a <resultMap> element, but there are limitations. There is no way to specify the types of the output columns (if needed), there is no …

ibatis: 能select出对象,但对象的每个属性都是null ? Read More »

活学活用一把: 通过引入Indirection来降低Connascence

有句著名的话叫做"All problems in computer science can be solved by another level of indirection". 另有人(page-jones)研究过耦合(connascence)的种类,并提出 通过把某种耦合变成另一种耦合,可以减弱耦合的程度. 今天终于有机会使用这两个著名的东西了. 问题是这样的. 你的合作方比较强势, 不愿意按契约来设计. 你的系统想知道"这个流程执行完后,倒底谁拿到了标书? ", 对方告诉你, "我们不提供’谁拿到了标书’这个接口,你可以使用’竞标者是不是市委干部的儿子或女婿’这个接口,因为他们一旦竞标,合同肯定就是他们的" 而你又相信"人间或许还有点公义,现在他们能拿到,以后就未必了". 但前面说了,对方很强势,于是干脆不搭理你. 如果你按他们的意思来,那你们就没有严格地按照契约来定义接口: 他给你的东西不是你直接想要的东西,而是你想要的东西的背后的东西. 如果你直接依赖"竞标者是太子"这个接口,万一这玩意儿靠不住了,你就得改你的系统. 从Connascence的角度来说, 这里存在一个Connascence of Algorithm(算法耦合性), 你们两个系统之间的正确交互依赖于 "高干子弟必定拿标书" 这个脆弱的业务规则(算法). 那怎么解决这个问题? 既然对方不愿给真正的接口,那你就无法避免这个耦合; 但你仍要想办法减弱它对你的系统的影响; 也就是说, 算法被改变时,你的系统所做的修改要尽量小. 举例来说,如果你的系统中多处用到了这个接口,那一旦算法被改变,你的系统就有多处要改. 说到这里,解决方案已经呼之欲出了. 你要引入一个Adaptor作为indirection, 这个Adaptor在名义上提供你要的接口:"倒底是拿到了标书? ", 实现上它再依赖对方系统的"高干子弟拿标书"这个潜规则; 你的系统里要调用标书逻辑的地方都必须通过这个Adaptor, 而不能直接依赖对方的系统.如果对方改了这个逻辑,你只需要改你的Adapter这一个地方就可以了. 没错,耦合性还是存在,但你对未来的担扰至少少了些. 从Connascence的角度来说, 你是把耦合性 从"Connascence of Algorithm" 减弱为 "Connascence of name", …

活学活用一把: 通过引入Indirection来降低Connascence Read More »

OO方面的散乱笔记:《UML面向对象设计基础》

作者:Meilir Page-jones 1. 面向对象软件的可理解性和可维护性,以及其它一些特性都是以封装性和Connanscence为基础的 2. 包:里面的类来自同一领域,但它们未必相互发生影响;组件:里面的类相互作用完成一系列业务逻辑 (启示:平时应该注意把内聚、耦合这种理念扩展到对象之外,扩展到包、组件或者更高的级别) 3.高内聚/低耦合并不是oo的专利,在结构化时代就已有比较系统化的研究;这方面可以看作者的另一本经典书籍:’practical guide to structured systems design’,它里面提出的一些东西在OO时代照样有用. 4. Encumbrance:  一个类的encumbrance就是它直接引用和间接引用的所有类的数量。 越低层次的类,它的encumbrance就应该越小; 越高层次的类,它的encumbrance就应该越大。 5.一些错误的内聚:   a.混合事例型内聚:比如在“几何图形”这个类里搞一个“对角线”属生就是这种不当内聚,因为虽然四边形有对角线,但三角形并没有对角线。    b.混合领域型内聚:比如在“实数”这个类里写一个“华氏温度转摄氏温度”的方法,这样做会从扩大一个类的encumbrance,引入不相关的领域,导致可重用性降低   c.混合角色型内聚:比如在“人”这个类里写一个“拥有狗的数目”的方法。人和狗可能都属于业务领域,但人和狗完全是不同的角色。

connascence & coupling

越来越感觉到,弱耦合性是系统可维护性的关键, 有必要研究一下各种耦合的形态及相应解耦手段。 Robert C. Martin 在他的《敏捷软件开发》里提出了很多面向对象的原则,《代码大全》里也有一些,本质上都是为了实现弱耦合。 对耦合这个概念本身贡献最大的人可能是Meilir Page-Jones,他在他的《UML面向对象设计基础》中使用了connascence这个词(单词里的第一个a发/ei/音)。 Connascence就是Coupling的同义词,Page-Jones给出了它的定义,还指出了它有几种类别。 另有一个叫 Jim Weirich的Ruby高手对connascence非常感兴趣。他把它称为OO理论中的Grand Unified Theory(物理学术语). 他在一次演讲中专门介绍了这个东西,并有一定的展开。 我本想找一本专门讲弱耦合的书,但可惜目前没有; 于是只好自己研究一下上面提到的材料,下面是一些笔记。 附资源: connascence的wiki页面: http://en.wikipedia.org/wiki/Connascent_software_components Meilir Page-Jones的书:Fundamentals of Object-Oriented Design in UML, 看第三部分就好 Jim Weirich的演讲:http://confreaks.net/videos/77-mwrc2009-the-building-blocks-of-modularity ==================================================================== Connascence的定义:两个软件元素A和B之间,如果A改变,B也就必须改变, 或者当某第三方元素发生改变时,A和B必须同时改变。 ———————————————————- 各种Connascence: 静态Connascence: 1. connascence of name   methodA()改名为methodB()时, 调用methodA()的地方都要改名 2. connascense of type or class   如果变量从值100变成了一个很大的数, 则变量类型可能要从int改成BigInteger 3.connascense of convention   magic …

connascence & coupling Read More »