﻿<?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-WEB开发 de  点滴-随笔分类-easymock</title><link>http://www.blogjava.net/sanwish/category/35804.html</link><description>by sanwish</description><language>zh-cn</language><lastBuildDate>Fri, 07 Nov 2008 17:56:45 GMT</lastBuildDate><pubDate>Fri, 07 Nov 2008 17:56:45 GMT</pubDate><ttl>60</ttl><item><title>（转）手把手教你如何使用EasyMock</title><link>http://www.blogjava.net/sanwish/archive/2008/11/07/239161.html</link><dc:creator>sanwish</dc:creator><author>sanwish</author><pubDate>Fri, 07 Nov 2008 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/sanwish/archive/2008/11/07/239161.html</guid><wfw:comment>http://www.blogjava.net/sanwish/comments/239161.html</wfw:comment><comments>http://www.blogjava.net/sanwish/archive/2008/11/07/239161.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sanwish/comments/commentRss/239161.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sanwish/services/trackbacks/239161.html</trackback:ping><description><![CDATA[
		<div class="cnt" id="blog_text">
				<font size="3">
						<strong>
								<font color="#0000ff">背景：</font>
								<br />
						</strong>EasyMock 2 版本必须要 JDK5 才能使用 EasyMock 1.2 可以在 JDK 1.4 使用<br />也可以使用 Retrotranslator 将 EasyMock 2 版本改为 JDK 1.4 也可以使用的。<br />目前使用的是 EasyMock 2.2<br /><br /></font>
				<font color="#0000ff" size="3">
						<strong>准备：</strong>
				</font>
				<font size="3">
						<br />先弄个接口 Haha 用来 Mock 的，两个方法<br />void haha(String s);<br />String hehe(String s);<br /><br /><strong><font color="#0000ff">开始 Mock：</font></strong><br /><br /></font>
				<font color="#0000ff" size="3">静态导入 EasyMock</font>
				<font size="3">
						<br />import static org.easymock.EasyMock.*;<br /><br /></font>
				<font color="#0000ff" size="3">然后</font>
				<font size="3">
						<br />Haha haha=createMock(Haha.class);<br /><br />无返回值的调用可以直接调用 Mock 方法<br /><br />haha.haha("haha");<br /><br />有返回值的可以<br /><br />expect(haha.hehe("hehe")).andReturn("ok");<br /><br /></font>
				<font color="#0000ff" size="3">这样做完后</font>
				<font size="3">
						<br />
						<br />你要 replay(haha); 一下，表示录完 mock ，准备重放了。<br /><br />就可以调用 haha.haha("haha") 了，同样的，调用 haha.hehe("hehe") 的返回值是 "ok"<br /><br />全部调用完了，使用 verify(haha); 查看一下预期的调用是不是都调了，如果预期要调用一次，却没调，那就会 AssertionError 哦。<br /><br /></font>
				<font color="#0000ff" size="3">调用次数</font>
				<font size="3">
						<br />
						<br />上面这些都是默认调用一次，就相当于 expect(haha.hehe("hehe")).andReturn("ok").times(1); 或 expect(haha.hehe("hehe")).andReturn("ok").once();<br /><br />如果想调用任意次，就 expect(haha.hehe("hehe")).andReturn("ok").anyTimes();<br /><br />如果想最少调用一次，就 expect(haha.hehe("hehe")).andReturn("ok").atLeastOnce();<br /><br />如果想调用 1 至 3 次，就 expect(haha.hehe("hehe")).andReturn("ok").times(1,3);<br /><br /></font>
				<font color="#0000ff" size="3">预期的结果<br /></font>
				<font color="#000000" size="3">
						<br />还可以 expect(haha.hehe("hehe")).andReturn("ok").andReturn("ok too").andThrow(new RuntimeException());<br /><br />这样，第一次调用 haha.hehe("hehe") 时返回 "ok" ，第二次返回 "ok too"，第三次调用就比较惨了，会抛出一个 RuntimeException，需要注意</font>
				<font size="3">的是，如果抛出的异常是 unchecked 的，就是 Runtime 的，就随便抛，如果是 checked 的，那就一定要抛这个方法定义的，否则会在 andThrow 这行出 IllegalArgumentException 。<br /><br />终极解决办法还可以使用 andAnswer(IAnswer&lt;T&gt; answer) 传一个实现 IAnswer 接口的实例，这个接口只有一个方法<br />T answer() throws Throwable;<br />随便你返回什么，或是抛出什么异常。<br /><br /></font>
				<font color="#0000ff" size="3">调用顺序</font>
				<font size="3">
						<br />
						<br />不 过如上面所说，haha.haha("haha") 与 haha.hehe("hehe") 是没有顺序的，将 createMock 改成 createStrictMock 或在 createMock 后面加一行 checkOrder(haha,true) 就可以了，这时，就一定要按照定义的顺序来调用了。<br /><br />如果多个不同的 mock 也要保证顺序呢？那就不能使用 createMock 来创建这些 mock 了，因为每次 createMock 都会使用一个新的 IMocksControl 实例来单独控制这个 mock ，我们希望将多个 mock 用同一个 IMocksControl 控制，只需要<br /><br />IMocksControl ctrl = createStrictControl();<br />Haha haha1= ctrl.createMock(Haha .class);<br />Haha haha2 = ctrl.createMock(Haha .class);<br /><br />haha1.haha("haha1");<br />haha2.haha("haha2");<br /><br />ctrl.replay();<br /><br />就可以了<br /><br /></font>
				<font color="#0000ff" size="3">预期的参数<br /></font>
				<font size="3">
						<br />刚才 haha.haha("haha") 中的 "haha" 就是预期的参数，EasyMock 提供了很多预期参数的方法，比如 haha.haha(eq("haha"))，与前面的方法功能完全一样<br />haha.haha((String)anyObject) 随便你传什么参数都没问题。<br />haha.haha(not(eq("haha"))) 这个只要不传 haha ，其它什么都成<br /><br />同 样可以自定义，只要调用     public static void reportMatcher(IArgumentMatcher matcher) 方法，将自定义的 IArgumentMatcher 传进去就可以了，这个接口有两个方法 boolean matches(Object argument)   和 void appendTo(StringBuffer buffer) 第一个方法的参数是调用实际传入的值，返回是否匹配，第二个方法是错误时向 buffer 中 append 错误信息。<br /><br /></font>
				<font color="#0000ff" size="3">将方法弄成 Stub<br /></font>
				<font size="3">
						<br />Stub 方法，我想应该就是随便调，爱怎么调就怎么调，返回的都是那个值，最后也不会验证到底调用了多少次。<br />如果想把一个方法弄成 Stub，无返回值的只要 asStub() 就是 expect(haha.haha("haha")).asStub() ，有返回值的就 andStubReturn() , andStubAnswer() 这样就可以了。<br /><br /></font>
				<font color="#0000ff" size="3">友好的Mock</font>
				<font size="3">
						<br />
						<br />我们使用 createMock 创建出来的 mock 对象，如果没有录过，调用这个方法都会出 AssertionError ，但如果使用 createNiceMock 就不会了，会返回 0 , null , false 这样的。</font>
		</div>
<img src ="http://www.blogjava.net/sanwish/aggbug/239161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sanwish/" target="_blank">sanwish</a> 2008-11-07 09:56 <a href="http://www.blogjava.net/sanwish/archive/2008/11/07/239161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>