<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta name="generator" content="pdf2htmlEX">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="https://static.pudn.com/base/css/base.min.css">
<link rel="stylesheet" href="https://static.pudn.com/base/css/fancy.min.css">
<link rel="stylesheet" href="https://static.pudn.com/prod/directory_preview_static/622b2fdf81ded46b7f17673d/raw.css">
<script src="https://static.pudn.com/base/js/compatibility.min.js"></script>
<script src="https://static.pudn.com/base/js/pdf2htmlEX.min.js"></script>
<script>
try{
pdf2htmlEX.defaultViewer = new pdf2htmlEX.Viewer({});
}catch(e){}
</script>
<title></title>
</head>
<body>
<div id="sidebar" style="display: none">
<div id="outline">
</div>
</div>
<div id="pf1" class="pf w0 h0" data-page-no="1"><div class="pc pc1 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://static.pudn.com/prod/directory_preview_static/622b2fdf81ded46b7f17673d/bg1.jpg"><div class="t m0 x1 h2 y1 ff1 fs0 fc0 sc0 ls0 ws0"> <span class="_ _0"></span><span class="ff2 fs1 ls1">Junit<span class="_"> </span><span class="ff3 sc1 ls2">中的设计模式</span><span class="fc1 ls3"> </span></span></div><div class="t m0 x2 h3 y2 ff2 fs0 fc1 sc0 ls3 ws0">JUnit<span class="_"> </span><span class="ff3 sc2 ls4">设计模式分析</span> </div><div class="t m0 x3 h4 y3 ff3 fs2 fc1 sc2 ls5 ws0">刘兵<span class="ff2 sc0 ls6"> (<span class="_ _1"></span><span class="ff3 sc2 ls5">技术顾问<span class="ff2 sc0 ls7 ws1"> bliu76@yeah.net) </span></span></span></div><div class="t m0 x4 h4 y4 ff2 fs2 fc1 sc0 ls3 ws0"> <span class="_"> </span><span class="ff3 sc2 ls5">该文章发表与</span><<span class="ff3 sc2 ls5">程序员</span><span class="ls8">>6<span class="_"> </span></span><span class="ff3 sc2">期</span> </div><div class="t m0 x5 h4 y5 ff2 fs2 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h5 y6 ff3 fs2 fc1 sc0 ls3 ws0">摘要<span class="ff1"> </span></div><div class="t m0 x6 h5 y7 ff1 fs2 fc1 sc0 ls9 ws2"> JUnit<span class="_ _2"> </span><span class="ff3 ls3 ws0">是一个优秀的<span class="_ _2"> </span><span class="ff1 lsa">Java<span class="_"> </span></span>单元测试框架,由两位世界级软件大师<span class="_ _2"> </span></span><span class="lsb ws3">Erich Gamma<span class="_ _3"></span> <span class="_"> </span><span class="ff3 ls3 ws0">和</span><span class="lsc ws4"> Kent <span class="_ _1"></span>Beck<span class="_ _2"> </span><span class="ff3 ls3 ws0">共同开发完</span></span></span></div><div class="t m0 x6 h5 y8 ff3 fs2 fc1 sc0 ls3 ws0">成。本文将向读者介绍在开发<span class="_ _2"> </span><span class="ff1 ls9">JUnit<span class="_"> </span></span>的过程中是怎样应用设计模式的。<span class="ff1"> </span></div><div class="t m0 x7 h5 y9 ff3 fs2 fc1 sc0 ls3 ws0">关键词:单元测试<span class="ff1 lsd ws5"> JUnit </span>设计模式<span class="ff1 lse"> </span></div><div class="t m0 x8 h6 ya ff1 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h7 yb ff4 fs3 fc1 sc0 lsf ws6">1 JUnit<span class="_ _4"> </span><span class="ff3 sc2 ls10 ws0">概述</span><span class="ls3 ws0"> </span></div><div class="t m0 x6 h8 yc ff4 fs4 fc1 sc0 ls11 ws7">1.1 JUnit<span class="_ _5"> </span><span class="ff3 sc2 ls12 ws0">概述</span><span class="ls3 ws0"> </span></div><div class="t m0 x9 h6 yd ff1 fs1 fc1 sc0 ls13 ws8"> JUnit<span class="_ _6"> </span><span class="ff3 ls3 ws0">是一个开源的<span class="_ _6"> </span><span class="ff1 ls14">java<span class="_"> </span></span>测试框架,<span class="_ _7"></span>它是<span class="_ _6"> </span><span class="ff1 ls15">XUnit<span class="_"> </span></span>测试体系架构的一种实现。<span class="_ _7"></span>在<span class="_ _6"> </span><span class="ff1 ls13">JUnit<span class="_"> </span></span>单元</span></div><div class="t m0 x6 h9 ye ff3 fs1 fc1 sc0 ls3 ws0">测试框架的设计时,<span class="_ _8"></span>设定了三个总体目标,<span class="_ _8"></span>第一个是简化测试的编写,<span class="_ _8"></span>这种简化包括测试框</div><div class="t m0 x6 h9 yf ff3 fs1 fc1 sc0 ls3 ws0">架的学习和实际测试单元的编写;<span class="_ _1"></span>第二个是使测试单元保持持久性;<span class="_ _1"></span>第三个则是可以利用既</div><div class="t m0 x6 h6 y10 ff3 fs1 fc1 sc0 ls3 ws0">有的测试来编写相关的测试。所以这些目的也是为什么使用模式的根本原因。<span class="ff1"> </span></div><div class="t m0 x6 h8 y11 ff4 fs4 fc1 sc0 ls11 ws7">1.2 JUnit<span class="_ _5"> </span><span class="ff3 sc2 ls12 ws0">开发者</span><span class="ls3 ws0"> </span></div><div class="t m0 xa h6 y12 ff1 fs1 fc1 sc0 ls16 ws0">JUnit<span class="_"> </span><span class="ff3 ls3">最初由<span class="_ _6"> </span></span><span class="ls17 ws9">Erich Ga<span class="_ _3"></span>mma <span class="_"> </span></span><span class="ff3 ls3">和</span><span class="ls18 wsa"> Kent <span class="_ _1"></span>Beck<span class="_ _2"> </span><span class="ff3 ls3 ws0">所开发。<span class="ff1 ls19">Erich Gamm<span class="_ _9"></span>a<span class="_"> </span><span class="ff3 ls3">博士是瑞士苏伊士国际</span></span></span></span></div><div class="t m0 x6 h6 y13 ff3 fs1 fc1 sc0 ls3 ws0">面向对象技术软件中心的技术主管,也是巨著《设计模式》的四作者之一。<span class="ff1 ls1a wsb">Kent Beck<span class="_ _6"> </span></span>先生</div><div class="t m0 x6 h6 y14 ff3 fs1 fc1 sc0 ls3 ws0">是<span class="_ _6"> </span><span class="ff1 ls1b">XP<span class="_ _a"></span><span class="ff3 ls3">(<span class="ff1 ls1c wsc">Extreme Programming<span class="_ _9"></span><span class="ff3 ls3 ws0">)<span class="_ _a"></span>的创始人,<span class="_ _a"></span>他倡导软件开发的模式定义,<span class="_ _a"></span><span class="ff1 ls1d">CRC<span class="_"> </span><span class="ff3 ls3">卡片在软件开</span></span></span></span></span></span></div><div class="t m0 x6 h6 y15 ff3 fs1 fc1 sc0 ls3 ws0">发过程中的使用,<span class="_ _1"></span>基于<span class="_ _6"> </span><span class="ff1 ls15">XUnit<span class="_"> </span></span>的测试框架,<span class="_ _1"></span>重新评估了在软件开发过程中测试优先的编程模</div><div class="t m0 x6 h6 y16 ff3 fs1 fc1 sc0 ls1e ws0">式<span class="_ _2"> </span>。是《<span class="_ _2"> </span><span class="ff1 ls1f wsd">The Sm<span class="_ _9"></span>alltalk Best Practice Patterns<span class="_ _9"></span><span class="ff3 ls3 ws0">》<span class="_ _b"></span>、<span class="_ _c"></span>《<span class="ff1 ls1c wsc">Extreme Program<span class="_ _9"></span>ming Explained<span class="_ _9"></span><span class="ff3 ls1e ws0">》和《<span class="_ _2"> </span><span class="ff1 ls1c">Planning </span></span></span></span></span></div><div class="t m0 x6 h6 y17 ff1 fs1 fc1 sc0 ls20 wse">Extreme Program<span class="_ _9"></span>ming<span class="ff3 ls3 ws0">(与<span class="_ _6"> </span></span><span class="ls21 wsf">Martin Fowler<span class="_"> </span><span class="ff3 ls3 ws0">合著)<span class="_ _b"></span>》的作者。<span class="ff1"> </span></span></span></div><div class="t m0 xa h6 y18 ff3 fs1 fc1 sc0 ls3 ws0">由于<span class="_ _5"> </span><span class="ff1 ls16">JUnit<span class="_ _4"> </span></span>是两位世界级大师的作品,所以值得大家细细品味,现在就把<span class="_ _5"> </span><span class="ff1 ls16">JUnit<span class="_ _5"> </span></span>中使用</div><div class="t m0 x6 h9 y19 ff3 fs1 fc1 sc0 ls3 ws0">的设计模式总结出来与大家分享。<span class="_ _7"></span>将按照问题的提出,<span class="_ _7"></span>模式的选择,<span class="_ _7"></span>具体实现,<span class="_ _7"></span>使用效果这</div><div class="t m0 x6 h6 y1a ff3 fs1 fc1 sc0 ls3 ws0">种过程展示如何将模式应用于<span class="_ _6"> </span><span class="ff1 ls16">JUnit</span>。<span class="ff1"> </span></div><div class="t m0 x6 h7 y1b ff4 fs3 fc1 sc0 lsf ws6">2 JUnit<span class="_ _4"> </span><span class="ff3 sc2 ls10 ws0">体系架构</span><span class="ls3 ws0"> </span></div><div class="t m0 x9 h6 y1c ff1 fs1 fc1 sc0 ls16 ws0">JUnit<span class="_"> </span><span class="ff3 ls3">的设计使用以<span class="_ _6"> </span></span><span class="ls22 ws10">Patterns Generate <span class="_ _a"></span>Architectures<span class="_ _b"></span><span class="ff3 ls3 ws0">(请参见<span class="ff1 ls23 ws11">"Patterns Generate <span class="_ _a"></span>Architectures", </span></span></span></div><div class="t m0 x6 h6 y1d ff1 fs1 fc1 sc0 ls24 ws12">Kent Beck and Ra<span class="_ _9"></span>lph Johnson, E<span class="_ _9"></span>COOP<span class="_ _9"></span> 94<span class="ff3 ls3 ws0">)的方式来架构系统。其设计思想是通过从零开始</span></div><div class="t m0 x6 h6 y1e ff3 fs1 fc1 sc0 ls3 ws0">来应用设计模式,然后一个接一个,直至你获得最终合适的系统架构。<span class="ff1 ls25"> </span></div><div class="t m0 x6 ha y1f ff2 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h5 y20 ff1 fs2 fc1 sc0 ls26 ws0">Junit<span class="_"> </span><span class="ff3 ls3">源码解析</span><span class="ls27 ws13"> <span class="_ _d"> </span>1/1 </span></div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
</body>
</html>
<div id="pf2" class="pf w0 h0" data-page-no="2"><div class="pc pc2 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://static.pudn.com/prod/directory_preview_static/622b2fdf81ded46b7f17673d/bg2.jpg"><div class="t m0 x1 h2 y1 ff1 fs0 fc0 sc0 ls0 ws0"> <span class="_ _0"></span><span class="ff2 fs1 ls1">Junit<span class="_"> </span><span class="ff3 sc1 ls2">中的设计模式</span><span class="fc1 ls3"> </span></span></div><div class="t m0 x6 h7 y21 ff4 fs3 fc1 sc0 ls28 ws6">3 JUnit<span class="_ _4"> </span><span class="ff3 sc2 ls10 ws0">设计模式</span><span class="ls3 ws0"> </span></div><div class="t m0 x6 h8 y22 ff4 fs4 fc1 sc0 ls29 ws14">3.1 Command<span class="ff3 sc2 ls12 ws0">(命令)模式</span><span class="ls3 ws0"> </span></div><div class="t m0 x6 hb y23 ff4 fs5 fc1 sc0 ls2a ws0">3.1.1 <span class="_"> </span><span class="ff3 sc2 ls2b">问题</span><span class="ls3"> </span></div><div class="t m0 x6 h6 y24 ff1 fs1 fc1 sc0 ls25 ws0"> J<span class="_ _e"></span>U<span class="_ _e"></span>n<span class="_ _e"></span>i<span class="_ _e"></span>t<span class="_ _9"></span><span class="ff3 ls3">是一<span class="_ _9"></span>个测试<span class="_ _2"> </span><span class="ff1 ls18">framework</span>,<span class="_ _b"></span>测试人员只需开发测试用例。<span class="_ _b"></span>然后把这些测试用例<span class="_ _b"></span>(<span class="ff1 ls2c">T<span class="_ _a"></span>estCase<span class="ff3 ls3">)</span></span></span></div><div class="t m0 x6 h6 y25 ff3 fs1 fc1 sc0 ls3 ws0">组成请求<span class="ff1">(</span>可能是一个或者多个<span class="ff1">)</span><span class="ls2d">,发<span class="_ _2"> </span>送<span class="_ _6"> </span>到<span class="_ _f"> </span><span class="ff1 ls16">JUnit</span></span>,<span class="_ _e"></span>然后由<span class="_ _6"> </span><span class="ff1 ls16">JUnit<span class="_"> </span></span>执行,<span class="_ _1"></span>最后报告详细测试结果。</div><div class="t m0 x6 h6 y26 ff3 fs1 fc1 sc0 ls3 ws0">其中包括执行的时间,错误方法,错误位置等。这样测试用例的开发人员就不需知道<span class="_ _10"> </span><span class="ff1 ls16">JUnit</span></div><div class="t m0 x6 h6 y27 ff3 fs1 fc1 sc0 ls3 ws0">内部的细节,<span class="_ _9"></span>只要符合它定义的请求格式即可。<span class="_ _9"></span>从<span class="_ _2"> </span><span class="ff1 ls16">JUnit<span class="_"> </span></span>的角度考虑,<span class="_ _9"></span>它并不需要知道请求</div><div class="t m0 x6 h6 y28 ff1 fs1 fc1 sc0 ls2e ws0">T<span class="_ _11"></span>estCase<span class="_"> </span><span class="ff3 ls3">的具体操作信息,<span class="_ _12"></span>仅把它当作一种命令来执行,<span class="_ _12"></span>然后把执行测试结果发给测试人员。</span></div><div class="t m0 x6 h6 y29 ff3 fs1 fc1 sc0 ls3 ws0">这样就使<span class="_ _6"> </span><span class="ff1 ls2f">JUnit <span class="_"> </span></span>框架和<span class="_ _6"> </span><span class="ff1 ls23">T<span class="_ _a"></span>estCase<span class="_"> </span><span class="ff3 ls3">的开发人员独立开来,<span class="_ _13"></span>使得请求的一方不必知道接收请求一</span></span></div><div class="t m0 x6 h6 y2a ff3 fs1 fc1 sc0 ls3 ws0">方的详细信息,更不必知道是怎样被接收,以及怎样被执行的,实现系统的松耦合。<span class="ff1"> </span></div><div class="t m0 x6 hb y2b ff4 fs5 fc1 sc0 ls2a ws0">3.1.2 <span class="_"> </span><span class="ff3 sc2 ls2b">模式的选择</span><span class="ls3"> </span></div><div class="t m0 x6 h6 y2c ff1 fs1 fc1 sc0 ls30 ws15"> Comman<span class="_ _3"></span>d<span class="ff3 ls3 ws0">(命令)模式(请参见<span class="_ _6"> </span></span><span class="ls16 ws16">Gamma, E., et al. Design Patterns: E<span class="_ _9"></span>lements of Reusable </span></div><div class="t m0 x6 h6 y2d ff1 fs1 fc1 sc0 ls21 wsf">Object-Oriented Software, <span class="_ _a"></span>Addison-W<span class="_ _a"></span>esley<span class="_ _11"></span>, Reading, MA, 1995<span class="ff3 ls3 ws0">)<span class="_ _8"></span>则能够比较好地满足需求。<span class="_ _8"></span>摘</span></div><div class="t m0 x6 h6 y2e ff3 fs1 fc1 sc0 ls31 ws0">引其意图(<span class="ff1 ls14">intent</span><span class="ls3">)<span class="_ _b"></span>,<span class="ff1">"</span><span class="ls31">将一个请求封装成一个对象,从而使你<span class="_ _9"></span>可用不同的请求对客户进行参</span></span></div><div class="t m0 x6 h6 y2f ff3 fs1 fc1 sc0 ls3 ws0">数化;对请求进行排队或记录请求日志<span class="ff1 ls1f">..."Com<span class="_ _9"></span>mand<span class="_"> </span><span class="ff3 ls3">模式告诉我们可以为一个操作生成一个</span></span></div><div class="t m0 x6 h6 y30 ff3 fs1 fc1 sc0 ls3 ws0">对象并给出它的一个<span class="ff1 ls32">"execute</span>(执行)<span class="ff1">"</span>方法。<span class="ff1"> </span></div><div class="t m0 x6 hb y31 ff4 fs5 fc1 sc0 ls2a ws0">3.1.3 <span class="_"> </span><span class="ff3 sc2 ls2b">实现</span><span class="ls3"> </span></div><div class="t m0 x6 h6 y32 ff1 fs1 fc1 sc0 ls25 ws0"> <span class="ff3 ls3">为了实现<span class="_ _5"> </span></span><span class="ls33">Co<span class="_ _3"></span>mmand<span class="_ _4"> </span><span class="ff3 ls3">模式,首先定义了一个接口<span class="_ _5"> </span></span><span class="ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>,<span class="_ _14"></span><span class="ff3 ls3">其中<span class="_ _6"> </span></span><span class="ls35">Run<span class="_ _4"> </span><span class="ff3 ls3">便是<span class="_ _5"> </span></span><span class="ls36">Command<span class="_ _4"> </span><span class="ff3 ls3">的<span class="_ _5"> </span></span><span class="ls20">Execute</span></span></span></span></span></div><div class="t m0 x6 h6 y33 ff3 fs1 fc1 sc0 ls3 ws0">方法。<span class="_ _7"></span>然后又使用<span class="_ _6"> </span><span class="ff1 ls37 ws17">Default Adapter<span class="_ _6"> </span></span>模式为这个接口提供缺省实现的抽象类<span class="_ _6"> </span><span class="ff1 ls2e">T<span class="_ _a"></span>estCase<span class="ff3 ls3">,<span class="_ _a"></span>这样开</span></span></div><div class="t m0 x6 h6 y34 ff3 fs1 fc1 sc0 ls3 ws0">发人员就可以从这个缺省实现进行继承,而不必从<span class="_ _6"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _5"> </span></span>接口直接实现。<span class="ff1"> </span></div><div class="t m0 xb hc y35 ff5 fs6 fc1 sc0 ls38 ws0">Te<span class="_ _3"></span>s<span class="_ _15"></span>t</div><div class="t m0 xb hc y36 ff5 fs6 fc1 sc0 ls39 ws0">run()</div><div class="t m0 xc hd y37 ff6 fs6 fc1 sc0 ls3a ws0">T<span class="_ _9"></span>e<span class="_ _9"></span>stC<span class="_ _a"></span>ase</div><div class="t m0 xd hc y38 ff5 fs6 fc1 sc0 ls3b ws0">ru<span class="_ _11"></span>n<span class="_ _11"></span>(<span class="_ _7"></span>)</div><div class="t m0 xe h6 y39 ff1 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h6 y3a ff3 fs1 fc1 sc0 ls3c ws0">我们首先来分析<span class="_ _f"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _16"> </span></span>接口,它有一个<span class="_ _f"> </span><span class="ff1 ls37">countT<span class="_ _11"></span>estCases<span class="_ _17"> </span><span class="ff3 ls3c">方法,用来统计这次测试有多少个</span></span></div><div class="t m0 x6 h6 y3b ff1 fs1 fc1 sc0 ls2e ws0">T<span class="_ _11"></span>estCase<span class="ff3 ls3">,<span class="_ _b"></span>另外一个方法就是<span class="_ _18"> </span><span class="ff1 ls33">Comma<span class="_ _3"></span>nd<span class="_ _18"> </span></span>模式的<span class="_ _2"> </span><span class="ff1 ls22">Excecute<span class="_ _18"> </span></span>方法,<span class="_ _19"></span>这里命名为<span class="_ _18"> </span><span class="ff1 ls23">run</span>,<span class="_ _19"></span>参数<span class="_ _18"> </span><span class="ff1 ls3d">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>R<span class="_ _14"></span>e<span class="_ _14"></span>s<span class="_ _14"></span>u<span class="_ _14"></span>l<span class="_ _14"></span>t</span></span></div><div class="t m0 x6 h6 y3c ff3 fs1 fc1 sc0 ls3 ws0">用来统计测试结果<span class="ff1"> </span></div><div class="t m0 xf he y3d ff7 fs2 fc2 sc0 ls3e ws0">public interface Test { </div><div class="t m0 xf he y3e ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e"> <span class="_ _8"></span> <span class="_ _7"></span> <span class="_ _8"></span> <span class="_ _7"></span> <span class="_ _8"></span> <span class="_ _7"></span>// Counts the number of test cases that will be run by this test. </span></div><div class="t m0 xf he y3f ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e ws18"> public <span class="_ _15"> </span>abstract <span class="_ _1a"> </span>int <span class="_ _1a"> </span>countTestCases(); </span></div><div class="t m0 x10 he y40 ff7 fs2 fc2 sc0 ls3e ws0">//runs a test and collects its result in a TestResult instance. </div><div class="t m0 xf he y41 ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e ws18"> public <span class="_ _15"> </span>abstract <span class="_ _1a"> </span>void <span class="_ _1a"> </span>run(TestResult <span class="_ _15"></span>result); </span></div><div class="t m0 x6 ha y1f ff2 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h5 y20 ff1 fs2 fc1 sc0 ls26 ws0">Junit<span class="_"> </span><span class="ff3 ls3">源码解析</span><span class="ls27 ws13"> <span class="_ _d"> </span>2/2 </span></div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
<div id="pf3" class="pf w0 h0" data-page-no="3"><div class="pc pc3 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://static.pudn.com/prod/directory_preview_static/622b2fdf81ded46b7f17673d/bg3.jpg"><div class="t m0 x1 h2 y1 ff1 fs0 fc0 sc0 ls0 ws0"> <span class="_ _0"></span><span class="ff2 fs1 ls1">Junit<span class="_"> </span><span class="ff3 sc1 ls2">中的设计模式</span><span class="fc1 ls3"> </span></span></div><div class="t m0 xf he y42 ff7 fs2 fc2 sc0 ls3e ws0">} </div><div class="t m0 x6 h6 y43 ff1 fs1 fc1 sc0 ls2e ws0">T<span class="_ _11"></span>estCase<span class="_"> </span><span class="ff3 ls3">是该接口的抽象实现,<span class="_ _1b"></span>它增加了一个测试名称属性,<span class="_ _1b"></span>因为每一个<span class="_ _6"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _3"></span>C<span class="_ _14"></span>a<span class="_ _14"></span>s<span class="_ _14"></span>e<span class="_ _4"> </span></span>在创建时</span></div><div class="t m0 x6 h6 y44 ff3 fs1 fc1 sc0 ls3 ws0">都要有一个名称,如果一个测试失败了,便可识别出是哪个测试失败。<span class="ff1"> </span></div><div class="t m0 xf he y45 ff7 fs2 fc2 sc0 ls3e ws0">public <span class="fc3">abstract</span> class TestCase extends Assert implements Test { </div><div class="t m0 xf he y46 ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e"> <span class="_ _8"></span> <span class="_ _7"></span> <span class="_ _8"></span> <span class="_ _7"></span>//the name of the test case </span></div><div class="t m0 xf he y47 ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e ws18"> private <span class="_ _15"> </span>String <span class="_ _1a"> </span>fName; </span></div><div class="t m0 x11 he y48 ff7 fs2 fc2 sc0 ls3e ws0">public void run(TestResult result) { </div><div class="t m0 xf he y49 ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3e ws18"> <span class="_ _1c"> </span> result.run(this); </span></div><div class="t m0 xf he y4a ff7 fs2 fc2 sc0 ls3 ws0"> <span class="_ _1"></span><span class="ls3f"> }<span class="_ _15"> </span> </span></div><div class="t m0 xf he y4b ff7 fs2 fc2 sc0 ls3e ws0">} </div><div class="t m0 x6 h6 y4c ff3 fs1 fc1 sc0 ls3 ws0">这样测试人员,编写测试用例时,只需继承<span class="_ _5"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>C<span class="_ _3"></span>a<span class="_ _14"></span>s<span class="_ _14"></span>e<span class="_ _14"></span></span>,来完成<span class="_ _5"> </span><span class="ff1 ls23">run<span class="_ _5"> </span></span>方法即可,然后<span class="_ _5"> </span><span class="ff1 ls16">JUnit<span class="_ _5"> </span></span>获</div><div class="t m0 x6 h6 y4d ff3 fs1 fc1 sc0 ls3 ws0">得测试用例的请求,执行它的<span class="_ _6"> </span><span class="ff1 ls23">run<span class="_"> </span></span>方法,把测试结果记录在<span class="_ _6"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>R<span class="_ _3"></span>e<span class="_ _14"></span>s<span class="_ _14"></span>u<span class="_ _14"></span>l<span class="_ _14"></span>t<span class="_ _4"> </span></span>之<span class="_ _9"></span>中,目前可以暂且</div><div class="t m0 x6 h6 y4e ff3 fs1 fc1 sc0 ls3 ws0">这样理解。<span class="ff1"> </span></div><div class="t m0 x6 hb y4f ff4 fs5 fc1 sc0 ls2a ws0">3.1.4 <span class="_"> </span><span class="ff3 sc2 ls2b">效果</span><span class="ls3"> </span></div><div class="t m0 x6 h6 y50 ff3 fs1 fc1 sc0 ls3 ws0">下面来考虑经过使用<span class="_ _6"> </span><span class="ff1 ls40">Co<span class="_ _3"></span>mman<span class="_ _3"></span>d<span class="_ _6"> </span></span>模式后给系统的架构带来了那些效果:<span class="ff1"> </span></div><div class="t m0 x6 h6 y51 ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls40">Co<span class="_ _3"></span>mman<span class="_ _3"></span>d<span class="_ _6"> </span><span class="ff3 ls3">模式将实现请求的一方(</span><span class="ls23">T<span class="_ _11"></span>estCase<span class="_"> </span><span class="ff3 ls3">开发)和调用一方(</span><span class="ls22">JUnit <span class="_"> </span><span class="ff3 ls3">)进行解藕<span class="ff1"> </span></span></span></span></span></div><div class="t m0 x6 h6 y52 ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls33">Comman<span class="_ _3"></span>d<span class="_"> </span><span class="ff3 ls3">模式使新的<span class="_ _6"> </span></span><span class="ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>C<span class="_ _14"></span>a<span class="_ _14"></span>s<span class="_ _3"></span>e<span class="_ _4"> </span><span class="ff3 ls3">很容易加入,<span class="_ _9"></span>无需改变已有的类,<span class="_ _9"></span>只需继承<span class="_ _6"> </span><span class="ff1 ls2e">T<span class="_ _11"></span>estCase<span class="_"> </span><span class="ff3 ls3">类</span></span></span></span></span></div><div class="t m0 xa h6 y53 ff3 fs1 fc1 sc0 ls3 ws0">即可,这样方便了测试人员<span class="ff1"> </span></div><div class="t m0 x6 h6 y54 ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls33">Comman<span class="_ _3"></span>d<span class="_ _4"> </span><span class="ff3 ls3">模式可以将多个<span class="_ _5"> </span></span><span class="ls23">T<span class="_ _11"></span>estCase<span class="_ _5"> </span><span class="ff3 ls3">进行组合成一个复合命令,你将看到<span class="_ _5"> </span></span><span class="ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>S<span class="_ _14"></span>u<span class="_ _14"></span>i<span class="_ _14"></span>t<span class="_ _4"> </span><span class="ff3 ls3">就是</span></span></span></span></div><div class="t m0 xa h6 y55 ff3 fs1 fc1 sc0 ls3 ws0">它的复合命令,当然它使用了<span class="_ _6"> </span><span class="ff1 ls41">Composite<span class="_"> </span></span>模式<span class="ff1"> </span></div><div class="t m0 x6 h6 y56 ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls33">Comman<span class="_ _3"></span>d<span class="_ _5"> </span><span class="ff3 ls3">模式容易把请求的<span class="_ _5"> </span></span><span class="ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _1d"></span>C<span class="_ _1d"></span>a<span class="_ _14"></span>s<span class="_ _1d"></span>e<span class="_ _10"> </span><span class="ff3 ls3">组合成请求队列,这样使接收请求的一方(</span><span class="ls14">Junit </span></span></span></div><div class="t m0 xa h6 y57 ff1 fs1 fc1 sc0 ls18 ws0">Fromwork<span class="ff3 ls3">)<span class="ff1">,</span>容易决定是<span class="_ _3"></span>否执行请求,一旦发现<span class="_ _3"></span>测试用例失败或者错误可以立<span class="_ _3"></span>刻停止进</span></div><div class="t m0 xa h6 y58 ff3 fs1 fc1 sc0 ls3 ws0">行报告<span class="ff1"> </span></div><div class="t m0 x6 h6 y59 ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls33">Comman<span class="_ _3"></span>d<span class="_"> </span><span class="ff3 ls3">模式可以在需要的情况下,方便实现对请求的<span class="_ _6"> </span></span><span class="ls42">Undo<span class="_"> </span><span class="ff3 ls3">和<span class="_ _2"> </span></span><span class="ls35">Redo<span class="ff3 ls3">,<span class="_ _9"></span>以及记录<span class="_ _6"> </span><span class="ff1 ls43">Log,</span></span></span></span></span></div><div class="t m0 xa h6 y5a ff3 fs1 fc1 sc0 ls3 ws0">这部分目前在<span class="_ _6"> </span><span class="ff1 ls16">JUnit<span class="_"> </span></span>中还没有实现,将来是很容易加入的<span class="ff1"> </span></div><div class="t m0 x6 h8 y5b ff4 fs4 fc1 sc0 ls44 ws19">3.2 Composite<span class="ff3 sc2 ls12 ws0">(组合)</span><span class="ls3 ws0"> </span></div><div class="t m0 x6 hb y5c ff4 fs5 fc1 sc0 ls2a ws0">3.2.1 <span class="_"> </span><span class="ff3 sc2 ls2b">问题</span><span class="ls3"> </span></div><div class="t m0 xa h6 y5d ff3 fs1 fc1 sc0 ls3 ws0">为了获得对系统测试的信心,<span class="_ _a"></span>需要运行多个测试用例。<span class="_ _a"></span>通过使用<span class="_ _6"> </span><span class="ff1 ls33">Comma<span class="_ _3"></span>nd<span class="_ _6"> </span></span>模式,<span class="_ _a"></span><span class="ff1 ls45">JUn<span class="_ _3"></span>it</span></div><div class="t m0 x6 h9 y5e ff3 fs1 fc1 sc0 ls3 ws0">能够方便的运行一个单独的测试用例之后产生测试结果。<span class="_ _1"></span>可是在实际的测试过程中,<span class="_ _1"></span>需要把</div><div class="t m0 x6 h6 y5f ff3 fs1 fc1 sc0 ls3 ws0">多个测试用例进行组合成为一个复合的测试用例,当作一个请求发送给<span class="_ _4"> </span><span class="ff1 ls22">JUnit.</span><span class="ls46">这样<span class="_ _5"> </span><span class="ff1 ls16">JUnit<span class="_ _4"> </span></span></span>就</div><div class="t m0 x6 h6 y60 ff3 fs1 fc1 sc0 ls47 ws0">会面临一个问题,必须考虑测试<span class="_ _3"></span>请求的类型,是一个单<span class="_ _3"></span>一的<span class="_ _f"> </span><span class="ff1 ls2e">T<span class="_ _11"></span>estCase<span class="_ _16"> </span><span class="ff3 ls47">还是一个复合的</span></span></div><div class="t m0 x6 h6 y61 ff1 fs1 fc1 sc0 ls2e ws0">T<span class="_ _11"></span>estCase<span class="ff3 ls3">,甚至要区分到底有多少个<span class="_ _6"> </span></span><span class="ls23">T<span class="_ _a"></span>estCase<span class="ff3 ls3">。这样<span class="_ _6"> </span></span><span class="ls48">Junit<span class="_"> </span><span class="ff3 ls3">框架就要完成像下面这样的代码:<span class="_ _1e"></span><span class="ff1"> </span></span></span></span></div><div class="t m0 xa h6 y62 ff1 fs1 fc1 sc0 ls24 ws0">if<span class="ff3 ls3">(</span><span class="ls1d">isSingleT<span class="_ _a"></span>estCase(objectRequest)<span class="ff3 ls3">)<span class="ff1">{ </span></span></span></div><div class="t m0 xa h6 y63 ff1 fs1 fc1 sc0 ls25 ws0"> /<span class="_ _e"></span>/<span class="_ _e"></span><span class="ff3 ls3">如果是单个的<span class="_ _6"> </span><span class="ff1 ls22">T<span class="_ _11"></span>estCase,<span class="ff3 ls3">执行<span class="_ _6"> </span></span><span class="ls23">run<span class="ff3 ls3">,获得测试结果<span class="ff1"> </span></span></span></span></span></div><div class="t m0 xa h6 y64 ff1 fs1 fc1 sc0 ls37 ws1a"> (T<span class="_ _11"></span>estCase)objectRequest.run() </div><div class="t m0 xa h6 y65 ff1 fs1 fc1 sc0 ls20 wse">}else if(isCompositeT<span class="_ _a"></span>estCase(objectRequest)){ </div><div class="t m0 xa h6 y66 ff1 fs1 fc1 sc0 ls25 ws0"> /<span class="_ _e"></span>/<span class="_ _e"></span><span class="ff3 ls3">如果是一个复合<span class="_ _6"> </span><span class="ff1 ls22">T<span class="_ _11"></span>estCase,<span class="ff3 ls3">就要执行不同的操作,然后进行复杂的算法进行分<span class="ff1"> </span></span></span></span></div><div class="t m0 x10 h6 y67 ff1 fs1 fc1 sc0 ls24 ws0">//<span class="ff3 ls3">解,之后再运行每一个<span class="_ _6"> </span></span><span class="ls23">T<span class="_ _a"></span>estCase<span class="_ _3"></span><span class="ff3 ls3">,最后获得测试结果,同时又要考虑<span class="ff1"> </span></span></span></div><div class="t m0 x10 h6 y68 ff1 fs1 fc1 sc0 ls24 ws0">//<span class="ff3 ls3">如果中间测试出现错误怎么办????、<span class="ff1"> </span></span></div><div class="t m0 x6 ha y1f ff2 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h5 y20 ff1 fs2 fc1 sc0 ls26 ws0">Junit<span class="_"> </span><span class="ff3 ls3">源码解析</span><span class="ls27 ws13"> <span class="_ _d"> </span>3/3 </span></div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>
<div id="pf4" class="pf w0 h0" data-page-no="4"><div class="pc pc4 w0 h0"><img class="bi x0 y0 w1 h1" alt="" src="https://static.pudn.com/prod/directory_preview_static/622b2fdf81ded46b7f17673d/bg4.jpg"><div class="t m0 x1 h2 y1 ff1 fs0 fc0 sc0 ls0 ws0"> <span class="_ _0"></span><span class="ff2 fs1 ls1">Junit<span class="_"> </span><span class="ff3 sc1 ls2">中的设计模式</span><span class="fc1 ls3"> </span></span></div><div class="t m0 xa h6 y69 ff1 fs1 fc1 sc0 ls3 ws1b"> ………………………… </div><div class="t m0 xa h6 y6a ff1 fs1 fc1 sc0 ls3 ws1b"> ………………………… </div><div class="t m0 xa h6 y6b ff1 fs1 fc1 sc0 ls3 ws0">} </div><div class="t m0 x6 h6 y6c ff3 fs1 fc1 sc0 ls3 ws0">这会使<span class="_ _4"> </span><span class="ff1 ls16">JUnit<span class="_ _5"> </span></span>必须考虑区分请求(<span class="ff1 ls2e">T<span class="_ _11"></span>estCase<span class="_ _3"></span><span class="ff3 ls3">)的类型(是单个<span class="_ _4"> </span></span><span class="ls36">testCase<span class="_ _4"> </span><span class="ff3 ls3">还是复合<span class="_ _4"> </span></span><span class="ls1">testCase<span class="ff3 ls3">)<span class="_ _19"></span>,</span></span></span></span></div><div class="t m0 x6 h9 y6d ff3 fs1 fc1 sc0 ls3 ws0">而实际上大多数情况下,<span class="_ _8"></span>测试人员认为这两者是一样的。<span class="_ _8"></span>对于这两者的区别使用,<span class="_ _8"></span>又会使测</div><div class="t m0 x6 h6 y6e ff3 fs1 fc1 sc0 ls3 ws0">试用例的编写变得更加复杂,<span class="_ _9"></span>难以维护和扩展。<span class="_ _11"></span>于是要考虑,怎样设计<span class="_ _2"> </span><span class="ff1 ls16">JUnit<span class="_"> </span></span>才可以实现不</div><div class="t m0 x6 h6 y6f ff3 fs1 fc1 sc0 ls3 ws0">需要区分单个<span class="_ _6"> </span><span class="ff1 ls23">T<span class="_ _a"></span>estCase<span class="_ _6"> </span><span class="ff3 ls3">还是复合<span class="_ _6"> </span></span>T<span class="_ _11"></span>estCase<span class="ff3 ls3">,把它们统一成相同的请求?<span class="ff1"> </span></span></span></div><div class="t m0 xa h6 y70 ff1 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 hb y71 ff4 fs5 fc1 sc0 ls2a ws0">3.2.2 <span class="_"> </span><span class="ff3 sc2 ls2b">模式的选择</span><span class="ls3"> </span></div><div class="t m0 x6 h6 y72 ff1 fs1 fc1 sc0 ls25 ws0"> <span class="ff3 ls3">当<span class="_ _6"> </span></span><span class="ls13">JUnit<span class="_"> </span><span class="ff3 ls3">不必区分其运行的是一个或多个测试用例时,<span class="_ _7"></span>能够轻松地解决这个问题的模式就</span></span></div><div class="t m0 x6 h6 y73 ff3 fs1 fc1 sc0 ls3 ws0">是<span class="_ _6"> </span><span class="ff1 ls41">Composite<span class="_ _11"></span><span class="ff3 ls3">(组合)<span class="_ _9"></span>模式。<span class="_ _9"></span>摘引其意图,<span class="_ _9"></span><span class="ff1">"<span class="ff3">将对象组合成树形结构以表示</span>'<span class="ff3">部分</span>-<span class="ff3">整体</span>'<span class="ff3">的层次</span></span></span></span></div><div class="t m0 x6 h6 y74 ff3 fs1 fc1 sc0 ls49 ws0">结构。<span class="ff1 ls4a">Composite<span class="_ _f"> </span></span>使得用户对单个对象和组合对象的使用具有一致性。<span class="ff1 ls3">"<span class="_ _3"></span></span>在这里<span class="ff1 ls3">'</span>部分<span class="ff1 ls3">-<span class="_ _3"></span></span>整体<span class="ff1 ls3">'</span></div><div class="t m0 x6 h6 y75 ff3 fs1 fc1 sc0 ls3 ws0">的层次结构是解决问题的关键,可以把单个的<span class="_ _4"> </span><span class="ff1 ls2e">T<span class="_ _11"></span>estCase<span class="_ _4"> </span><span class="ff3 ls3">看作部分,而把复合的<span class="_ _4"> </span></span><span class="ls4b">T<span class="_ _11"></span>e<span class="_ _3"></span>stCa<span class="_ _3"></span>se<span class="_ _4"> </span><span class="ff3 ls3">看</span></span></span></div><div class="t m0 x6 h6 y76 ff3 fs1 fc1 sc0 ls3 ws0">作整体(称为<span class="_ _6"> </span><span class="ff1 ls34">Te<span class="_ _1d"></span>s<span class="_ _14"></span>t<span class="_ _14"></span>S<span class="_ _1d"></span>u<span class="_ _14"></span>i<span class="_ _14"></span>t<span class="_ _14"></span></span>)<span class="_ _19"></span>。这样使用该模式便可以恰到好处得解决了这个难题。<span class="ff1"> </span></div><div class="t m0 x9 h6 y77 ff3 fs1 fc1 sc0 ls3 ws0">首先看<span class="_ _6"> </span><span class="ff1 ls41">Composite<span class="_"> </span></span>模式的结构:<span class="ff1"> </span></div><div class="t m0 x9 h6 y78 ff1 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x12 h6 y79 ff1 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h6 y7a ff1 fs1 fc1 sc0 ls41 ws1c"> Composite<span class="_ _2"> </span><span class="ff3 ls3 ws0">模式引入以下的参与者:<span class="ff1"> </span></span></div><div class="t m0 xa h6 y7b ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls4c">Component<span class="ff3 ls3">:<span class="_ _9"></span>这是一个抽象角色,它给参加组合的对象规定一个接口。这个角色,</span></span></div><div class="t m0 x10 h6 y7c ff3 fs1 fc1 sc0 ls3 ws0">给出共有的接口和默认行为。其实就我们的<span class="_ _6"> </span><span class="ff1 ls34">Te<span class="_ _1d"></span>s<span class="_ _14"></span>t<span class="_ _4"> </span></span>接口,它定义出<span class="_ _6"> </span><span class="ff1 ls23">run<span class="_"> </span></span>方法。<span class="ff1"> </span></div><div class="t m0 xa h6 y7d ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1">Composite<span class="ff3 ls3">:<span class="_ _8"></span>实现共有接口并维护一个测试用例的集合。<span class="_ _8"></span>就是复合测试用例<span class="_ _2"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _1d"></span>S<span class="_ _14"></span>u<span class="_ _14"></span>i<span class="_ _1d"></span>t<span class="_ _14"></span> </span></span></span></div><div class="t m0 xa h6 y7e ff8 fs1 fc1 sc0 ls41 ws0"> <span class="_ _6"> </span><span class="ff1 ls1d">Leaf<span class="ff3 ls3">:<span class="_ _7"></span>代表参加组合的对象,<span class="_ _a"></span>它没有下级子对象,<span class="_ _a"></span>仅定义出参加组合的原始对象的</span></span></div><div class="t m0 x10 h6 y7f ff3 fs1 fc1 sc0 ls3 ws0">行为,其实就是单一的测试用例<span class="_ _6"> </span><span class="ff1 ls22">T<span class="_ _a"></span>estCase,<span class="ff3 ls3">它仅实现<span class="_ _6"> </span></span><span class="ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _4"> </span><span class="ff3 ls3">接口的方法。<span class="ff1"> </span></span></span></span></div><div class="t m0 x6 h6 y80 ff3 fs1 fc1 sc0 ls3 ws0">其实<span class="_ _f"> </span><span class="ff1 ls14">com<span class="_ _9"></span>ponsite<span class="_ _1f"> </span><span class="ff3 ls3">模式根据所实现的接口类型区分为两种形式,分别称为安全式和透明式。</span></span></div><div class="t m0 x6 h6 y81 ff1 fs1 fc1 sc0 ls16 ws0">JUnit<span class="_"> </span><span class="ff3 ls3">中使用了安全式的结构,这样在<span class="_ _6"> </span></span><span class="ls23">T<span class="_ _11"></span>estCase<span class="_"> </span><span class="ff3 ls3">中没有管理子对象的方法。<span class="ff1"> </span></span></span></div><div class="t m0 x6 hb y82 ff4 fs5 fc1 sc0 ls2a ws0">3.2.3 <span class="_"> </span><span class="ff3 sc2 ls2b">实现</span><span class="ls3"> </span></div><div class="t m0 xa h6 y83 ff1 fs1 fc1 sc0 ls14 ws0">composite<span class="_"> </span><span class="ff3 ls3">模式告诉我们要引入一个<span class="_ _6"> </span></span><span class="ls4d">Component<span class="_"> </span><span class="ff3 ls3">抽象类,为<span class="_ _6"> </span></span><span class="ls1d">Leaf<span class="_"> </span><span class="ff3 ls3">对象和<span class="_ _6"> </span></span><span class="ls4a">composite<span class="_"> </span><span class="ff3 ls46">对象</span></span></span></span></div><div class="t m0 x6 h6 y84 ff3 fs1 fc1 sc0 ls3 ws0">定义公共的接口。<span class="_ _9"></span>这个类的基本意图就是定义一个接口。<span class="_ _9"></span>在<span class="_ _6"> </span><span class="ff1 ls4e">Java<span class="_"> </span></span>中使用<span class="_ _6"> </span><span class="ff1 ls41">Composite<span class="_ _2"> </span></span>模式时,</div><div class="t m0 x6 h6 y85 ff3 fs1 fc1 sc0 ls3 ws0">优先考虑使用接口,而非抽象类,因此引入一个<span class="_ _4"> </span><span class="ff1 ls34">Te<span class="_ _14"></span>s<span class="_ _14"></span>t<span class="_ _1f"> </span></span>接口<span class="_ _9"></span>。当然我们的<span class="_ _4"> </span><span class="ff1 ls41">leaf<span class="_ _10"> </span></span>就是<span class="_ _4"> </span><span class="ff1 ls2e">T<span class="_ _11"></span>estCase</span></div><div class="t m0 x6 h6 y86 ff3 fs1 fc1 sc0 ls3 ws0">了。其源代码如下:<span class="ff1"> </span></div><div class="t m0 xf hf y87 ff7 fs2 fc2 sc0 ls3e ws0">//composite<span class="_ _18"> </span><span class="ff3 ls4f">模式中的<span class="_ _18"> </span></span>Component<span class="_ _2"> </span><span class="ff3 ls4f">角色</span><span class="ls3"> </span></div><div class="t m0 x6 ha y1f ff2 fs1 fc1 sc0 ls3 ws0"> </div><div class="t m0 x6 h5 y20 ff1 fs2 fc1 sc0 ls26 ws0">Junit<span class="_"> </span><span class="ff3 ls3">源码解析</span><span class="ls27 ws13"> <span class="_ _d"> </span>4/4 </span></div><div class="t m0 xf he y88 ff7 fs2 fc2 sc0 ls3e ws0">public interface Test { </div></div><div class="pi" data-data='{"ctm":[1.611639,0.000000,0.000000,1.611639,0.000000,0.000000]}'></div></div>