﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-爬虫工作室-随笔分类-单元测试</title><link>http://www.blogjava.net/gooogle/category/20836.html</link><description>思考Google</description><language>zh-cn</language><lastBuildDate>Wed, 28 Mar 2007 13:25:12 GMT</lastBuildDate><pubDate>Wed, 28 Mar 2007 13:25:12 GMT</pubDate><ttl>60</ttl><item><title>用easymock测试jdbc</title><link>http://www.blogjava.net/gooogle/archive/2007/03/21/105250.html</link><dc:creator>爬虫工作室</dc:creator><author>爬虫工作室</author><pubDate>Wed, 21 Mar 2007 05:29:00 GMT</pubDate><guid>http://www.blogjava.net/gooogle/archive/2007/03/21/105250.html</guid><wfw:comment>http://www.blogjava.net/gooogle/comments/105250.html</wfw:comment><comments>http://www.blogjava.net/gooogle/archive/2007/03/21/105250.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/gooogle/comments/commentRss/105250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gooogle/services/trackbacks/105250.html</trackback:ping><description><![CDATA[虽然以前用easymock测试过Dao，但那些Dao的实现，要么就hibernate，要么就用spring，而这两个框架的执行正确与否我们是不用关心的。JDBC是不是也这样测试了。答案是肯定的。<br />      这几天要用存储过程跟jdbc来做个项目，想想也有好长一段时间没用过JDBC来做项目了。该复习复习了。<br />      前阵子学了easymock，真好现在可以派上用场了。不过在测试的过程中还是遇到了不小问题，想来是自己基础不好的缘故。<br /><br />       这次不TDD了，太麻烦了。<br />       先看看我们要测试的代码<br />      
<div class="code_title">java 代码</div><div class="dp-highlighter"><div class="bar"> </div><ol class="dp-j"><li class="alt"><span><span>CallableStatementcstmt = </span><span class="keyword">null</span><span>;  </span></span></li><li class=""><span>        <span class="keyword">try</span><span> {  </span></span></li><li class="alt"><span>            cstmt = _conn.prepareCall(<span class="string">"{call LUCK_LOAD_COMMON(?,?)}"</span><span>);  </span></span></li><li class=""><span>            cstmt.setString(<span class="number">1</span><span>, </span><span class="string">"1"</span><span>);  </span></span></li><li class="alt"><span>            cstmt.registerOutParameter(<span class="number">2</span><span>, java.sql.Types.VARCHAR);  </span></span></li><li class=""><span>  </span></li><li class="alt"><span>            cstmt.executeUpdate();  </span></li><li class=""><span>            <span class="keyword">return</span><span> cstmt.getString(</span><span class="number">2</span><span>);  </span></span></li><li class="alt"><span>  </span></li><li class=""><span>        } <span class="keyword">catch</span><span> (Exception e) {  </span></span></li><li class="alt"><span>            GxDebug.logException(e);  </span></li><li class=""><span>            e.printStackTrace();  </span></li><li class="alt"><span>            <span class="keyword">return</span><span> </span><span class="keyword">null</span><span>;  </span></span></li><li class=""><span>        } <span class="keyword">finally</span><span> {  </span></span></li><li class="alt"><span>            <span class="keyword">if</span><span> (cstmt != </span><span class="keyword">null</span><span>)  </span></span></li><li class=""><span>                <span class="keyword">try</span><span> {  </span></span></li><li class="alt"><span>                    cstmt.close();  </span></li><li class=""><span>                } <span class="keyword">catch</span><span> (Exception e) {  </span></span></li><li class="alt"><span>            }  </span></li><li class=""><span>        }  </span></li></ol></div>  代码还挺长的。从上面的代码我们知道我们必须mock两个对象进去。一个是Connection， 一个是<span><span>CallableStatementcstmt 。<br />好再看看我们的测试代码<br /><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span>conn.prepareCall(</span><span class="string">"{call LUCK_LOAD_COMMON(?,?)}"</span><span>);  </span></span></li><li class=""><span>    conControl.setReturnValue(cstmt);  </span></li><li class="alt"><span>    conControl.replay();  </span></li><li class=""><span>      </span></li><li class="alt"><span>    cstmt.setString(<span class="number">1</span><span>, </span><span class="string">"1"</span><span>);  </span></span></li><li class=""><span>    cstmt.registerOutParameter(<span class="number">2</span><span>, java.sql.Types.VARCHAR);  </span></span></li><li class="alt"><span>    cstmt.executeUpdate();  </span></li><li class=""><span>    cstmtControl.setReturnValue(<span class="number">1</span><span>);  </span></span></li><li class="alt"><span>    cstmt.getString(<span class="number">2</span><span>);  </span></span></li><li class=""><span>    cstmtControl.setReturnValue(<span class="string">"5,4,3"</span><span>);  </span></span></li><li class="alt"><span>    cstmt.close();  </span></li><li class=""><span>    cstmtControl.replay();  </span></li><li class="alt"><span>      </span></li><li class=""><span>      </span></li><li class="alt"><span>    String rusult = dao.getNumber();  </span></li><li class=""><span>    Assert.assertEquals(<span class="string">"5,4,3"</span><span>, rusult);  </span></span></li><li class="alt"><span>      </span></li><li class=""><span>    conControl.verify();  </span></li><li class="alt"><span>    cstmtControl.verify();  </span></li></ol></div><br />oh，my got！测试代码比实现代码还要多。这段代码能执行吗？<br />我想可以的。easymock的原理是记录－回放的模式。<br />我想要做的工作是：<br />1，记录你mock对象的工作记录，比如上面的代码我们mock对象的工作记录是:<br /><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span>conn.prepareCall(</span><span class="string">"{call LUCK_LOAD_COMMON(?,?)}"</span><span>);  </span></span></li><li class=""><span>        conControl.setReturnValue(cstmt);  </span></li><li class="alt"><span>        cstmt.setString(<span class="number">1</span><span>, </span><span class="string">"1"</span><span>);  </span></span></li><li class=""><span>        cstmt.registerOutParameter(<span class="number">2</span><span>, java.sql.Types.VARCHAR);  </span></span></li><li class="alt"><span>        cstmt.executeUpdate();  </span></li><li class=""><span>        cstmtControl.setReturnValue(<span class="number">1</span><span>);  </span></span></li><li class="alt"><span>        cstmt.getString(<span class="number">2</span><span>);  </span></span></li><li class=""><span>        cstmtControl.setReturnValue(<span class="string">"5,4,3"</span><span>);  </span></span></li><li class="alt"><span>        cstmt.close();  </span></li><li class=""><span>  </span></li></ol></div><br /> 如果你工作记录的代码要求有返回值的话，那么你必须提供一个自定义的值给它，否则会报错。比如上面的<br /></span></span><span><li class="alt"><span> cstmt.getString(<span class="number">2</span><span>);  </span></span></li><li class=""><span>        cstmtControl.setReturnValue(<span class="string">"5,4,3"</span><span>);   //自己定义的返回值，用作以后的比较。</span></span><br />上面的是记录操作，回放的时候，easymock会把记录的操作跟你实际的代码进行比较，如果里面出了什么差错，那么不好意思你的代码有问题，请修正后再测试。<br /><br />如果有兴趣可以自己试下。</li></span><br /><br /><p>比如如果您 <br />conn.prepareCall("{call LUCK_LOAD_COMMON(?,?)}"); <br />修改为 <br />conn.prepareCall("{call LUCK_LOAD_COMMON(?,?，？)}"); <br />则出现的异常是： <br />junit.framework.AssertionFailedError: <br />Unexpected method call prepareCall("{call LUCK_LOAD_COMMON(?,?)}"): <br />prepareCall("{call LUCK_LOAD_COMMON(?,?)}"): expected: 0, actual: 1 <br />prepareCall("{call LUCK_LOAD_COMMON(?,?,?)}"): expected: 1, actual: 0<br /><br /></p><table width="100%"><tbody><tr><td><p>现在我总算是对ribbon说对于数据库的测试还是真实环境的好。 <br />因为你测试的时候你不知道存储过程是否正确。 <br />而且如果用真实的数据库测试，相对与mock测试，则简洁很多。而且清晰很多。 <br />上面只是在比较少逻辑的时候测试，如果代码逻辑复杂，我觉得写出来的测试代码会更复杂，这有引出，可能维护测试代码的工作比维护代码的工作更累</p></td></tr></tbody></table><script type="text/javascript"><!--
google_ad_client = "pub-9660229364187431";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text";
//2007-03-21: blogjava blog
google_ad_channel = "3226979720";
//--></script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script><img src ="http://www.blogjava.net/gooogle/aggbug/105250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gooogle/" target="_blank">爬虫工作室</a> 2007-03-21 13:29 <a href="http://www.blogjava.net/gooogle/archive/2007/03/21/105250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>