<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
PowerMockito經常會結合Mockito使用,先說一下這2個的介紹:
Mocktio和PowerMockito都是Mock的工具類,主要是Java的類庫,Mock就是偽裝的意思。
他們適用於單元測試中,對於單元測試來說,我們不希望依賴於第三方的元件,比如資料庫、Webservice等。在寫單元測試的時候,我們如果遇到了這些需要依賴第三方的情況,我們可以使用Mock的技術,偽造出來我們自己想要的結果。
對於Java而言,mock的物件主要是Java 方法和 Java類。
下面我就介紹一下怎麼使用Mockito和PowerMockito去進行Mock。
在我看來,PowerMockito是Mockito的一種增強,他們的PowerMockito可以呼叫Mockito的方法,但是對於Mocktio不能Mock的物件或者方法,我們可以使用PowerMockito來實現。
比如Mockito不能用於static Method, final method, 列舉類, private method,這些我們都可以用PowerMockito來實現,當PowerMockito和mockito結合使用的時候,我們需要考慮相容性的問題。
Mockito | PowerMockito |
---|---|
2.8.9+ | 2.x |
2.8.0-2.8.9 | 1.7.x |
2.7.5 | 1.7.0RC4 |
2.4.0 | 1.7.0RC2 |
2.0.0-beta - 2.0.42-beta | 1.6.5-1.7.0RC |
1.10.8 - 1.10.x | 1.6.2 - 2.0 |
1.9.5-rc1 - 1.9.5 | 1.5.0 - 1.5.6 |
1.9.0-rc1 & 1.9.0 | 1.4.10 - 1.4.12 |
1.8.5 | 1.3.9 - 1.4.9 |
1.8.4 | 1.3.7 & 1.3.8 |
1.8.3 | 1.3.6 |
1.8.1 & 1.8.2 | 1.3.5 |
1.8 | 1.3 |
1.7 | 1.2.5 |
Ref:https://github.com/powermock/powermock/wiki/Mockito
本文實現實現需要構造的介面和需要返回值的介面
<dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>2.0.2-beta</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.7.4</version> <scope>test</scope> </dependency> </dependencies>
ProcessDB.java
package com.github.mock.simple.vo; public class ProcessDB { public ProcessDB(String ss){ System.out.println(ss + " Enter ProcessDB ..."); } public ProcessDB(){ System.out.println("Enter ProcessDB ..."); } public void getResultOfConnectDBNoReturn(String ss) { System.out.println(ss + " Enter getResultOfConnectDBNoReturn ..."); } public String getResultOfConnectDB() { return "haha, Really went to the database"; } }
IUserService.java
package com.github.mock.simple.user; public interface IUserService { public String testedMehtod(); }
UserServiceImpl.java
package com.github.mock.simple.user.impl; import org.springframework.stereotype.Service; import com.github.mock.simple.user.IUserService; import com.github.mock.simple.vo.ProcessDB; @Service public class UserServiceImpl implements IUserService { @Override public String testedMehtod(){ System.out.println("Enter UserServiceImpl testedMehtod ..."); ProcessDB processDB = new ProcessDB("BB"); processDB.getResultOfConnectDBNoReturn("AA"); return processDB.getResultOfConnectDB(); } }
BussinessService.java
package com.github.mock.simple.user.impl; import com.github.mock.simple.vo.ProcessDB; public class BussinessService { public String testedMehtod() { System.out.println("Enter BussinessService testedMehtod ..."); ProcessDB processDB = new ProcessDB("BB"); processDB.getResultOfConnectDBNoReturn("AA"); return processDB.getResultOfConnectDB(); } }
MockSpringSimpleTest.java
package com.github.mock.simple.test; import java.text.MessageFormat; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.github.mock.simple.user.IUserService; import com.github.mock.simple.user.impl.BussinessService; import com.github.mock.simple.user.impl.UserServiceImpl; import com.github.mock.simple.vo.ProcessDB; @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)//Spring上下文 @PrepareForTest({BussinessService.class,UserServiceImpl.class}) @ContextConfiguration(locations = {"classpath:applicationContext-mock-inject.xml"}) public class MockSpringSimpleTest { //使用Spring上下文 @Autowired IUserService userService; @Mock ProcessDB processDB; //不使用Spring上下文時,使用該註解 @InjectMocks private BussinessService bussinessService; @Before public void initMocks() throws Exception { MockitoAnnotations.initMocks(this); //ReflectionTestUtils.setField(userService, "processDB", processDB); PowerMockito.whenNew(ProcessDB.class).withArguments("BB").thenReturn(processDB); // PowerMockito.whenNew(ProcessDB.class).withNoArguments().thenReturn(processDB); } @Test public void mockConnectDB() { String aa = "haha, everything is fake"; PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa); PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA"); System.out.println(bussinessService.testedMehtod()); Assert.assertEquals("haha, everything is fake", bussinessService.testedMehtod()); } @Test public void mockConnectDB2() { try { String aa = "haha, everything is fake"; PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa); PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA"); System.out.println(userService.testedMehtod()); Assert.assertEquals("haha, everything is fake", userService.testedMehtod()); } catch (Exception ex) { System.out.println("--- getMessage ---"); System.out.println(ex.getMessage()); System.out.println(); System.out.println("--- toString ---"); System.out.println(ex.toString()); System.out.println(); // System.out.println("--- printStackTrace ---"); // StringWriter stringWriter = new StringWriter(); // PrintWriter printWriter = new PrintWriter(stringWriter); // ex.printStackTrace(printWriter); // System.out.println(stringWriter.toString()); // System.out.println(); System.out.println("--- printStackTrace DIY ---"); System.out.println(ex.getClass().getName() + ": " + ex.getMessage()); StringBuilder sbException = new StringBuilder(); for (StackTraceElement ele : ex.getStackTrace()) { sbException.append(MessageFormat.format("tat {0}.{1}({2}:{3})n", ele.getClassName(), ele.getMethodName(), ele.getFileName(), ele.getLineNumber()));; } System.out.println(sbException); sbException = null; // stringWriter = null; // printWriter = null; } } }
最後applicationContext-mock-inject.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.github.mock.simple"/> </beans>
對於沒有實現類,但又被依賴的介面,在applicationContext-mock-inject.xml新增如下內容 (本文不需要):
<bean name="iXxService" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="com.github.mock.simple.api.IXxService"/> </bean>
同時在測試類裡面新增下面的程式碼:
@Mock iXxService iXxService;
在 @Before裡面新增下面的程式碼
ReflectionTestUtils.setField(userService, "iXxService", iXxService);
當IT中有些依賴元件無法正常整合,需要mock支援測試,可以使用power mockito。
當對一個物件進行powermockito,應該在prepare方法,統一mock這個物件。然後在其他方法,分別進行呼叫when,否則,多個方法內進行mock,會出錯。
比如有個 Service處於IT case的底層,普通的mock根本mock不進去,但我們又不能為了整合測試,為這個testcase單獨開一個口子,注入mock物件。power mockito強大的mock能力在這裡可以用上。
比如:
我的mock物件impalaService它在schmaMessagehandler類裡new出來的,則需要加上註解。
首先在test 類的開頭,加上註解頭部,頭部類是mock物件所在類。
@RunWith(PowerMockRunner.class) @PrepareForTest({HttpClient.class,SchemaMessageHandler.class})
其次:
PooledImpalaService impalaService = PowerMockito.mock(PooledImpalaService.class); PowerMockito.whenNew(PooledImpalaService.class).withArguments((ConfigurationanyObject()).thenReturn(impalaService); doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
使用powermockito,注意在用any()引數時候,比如
doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
參數列中,只要一個使用了any(),any****,則所有引數都要用any相關的引數,否則mock不成功。
總的來說,在it當中,只有你想mock一個物件,一定可以,比如你在A類中用到了B類,那麼在prepareForTest中增加A類的註解。
如下:
@PrepareForTest({A.class})然後,在it中 宣告一個B類,B b = PowerMockito.mock(B.class);這時候,就可以指定b的方法的返回值,或 PowerMockit.doNothing().when(b).方法名(),讓該方法什麼也不做。
最後,再講A範例化。PowerMockit是講究mock設定順序的。一定要注意。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45