Spring測試 其實很簡略。本站提示廣大學習愛好者:(Spring測試 其實很簡略)文章只能為提供參考,不一定能成為您想要的結果。以下是Spring測試 其實很簡略正文
在曩昔的職業生活裡,我常常發明有些人不寫測試代碼,而他們宣稱不寫的來由是沒法隨意馬虎地寫出籠罩多個分歧模塊的測試用例。好吧,我信任他們中的年夜部門要末是缺少一些比擬易控制的技巧手腕,要末就是沒時光來把它弄清晰,究竟任務中總會有進度之類的各類壓力。由於不曉得該若何測試,所以就常常疏忽集成測試,由此帶來的成績就是愈來愈蹩腳的軟件、愈來愈多的BUG和加倍掉望的客戶。所以我想分享一些小我的經歷,揭開集成測試奧秘的面紗。
若何對基於Spring的工程更好地停止集成測試
應用對象: Spring, JUnit, Mockito
想象有如許一個Spring工程,它集成了一些內部辦事,例如,一些銀行的web辦事。那末,為這個工程寫測試用例和在連續集成體系中完成這些測試時所碰到的成績根本都差不多:
1.每次測試都邑有生意業務停止,每次生意業務都須要支付金錢本錢,這些本錢終究由客戶承當;
2.測試時收回的過量的要求有能夠被以為是歹意要求,能夠形成在銀行的賬戶被封,效果是測試掉敗;
3.當應用非臨盆情況停止測試時,測試成果其實不非常靠得住,異樣,效果是測試掉敗。
平日情形下,你對單個類停止測試的時刻,成績很輕易處理,由於你可以虛擬一些內部辦事來供挪用。然則當對全部偉大的營業流程停止測試的時刻,意味你須要對多個部件停止測試,這時候,須要你將這些部件都歸入到Spring容器中停止治理。所幸,Spring包括了異常優良的測試框架,許可你未來自臨盆情況設置裝備擺設文件中的bean注入到測試情況中,然則對那些被挪用的內部辦事,須要我們本身去寫模仿完成。普通人第一反響能夠是在測試的setUp階段對由Spring注入的bean停止從新注入(修正),然則這類辦法須要再細心斟酌一下。
正告:經由過程這類方法,你的測試代碼打破了容器本身的行動,所以沒法包管在真實的情況中也如你測試的成果一樣。
現實上,我們無需先完成模仿類然後再把它從新注入到所需的bean中,我們可讓Spring贊助我們一開端就注入模仿類。讓我們用代碼演示一下。
示例工程包括一個名為BankService的類,代表挪用的內部辦事,一個名為UserBalanceService的類,它會挪用BankService。UserBalanceService完成的異常簡略,僅僅完成將余額從String向Double類型的轉換。
BankService.java的源碼:
public interface BankService { String getBalanceByEmail(String email); }
BankServiceImpl.java的源碼:
public class BankServiceImpl implements BankService { @Override public String getBalanceByEmail(String email) { throw new UnsupportedOperationException("Operation failed due to external exception"); } }
UserBalanceService.java的源碼:
interface UserBalanceService { Double getAccountBalance(String email); }
UserBalanceServiceImpl.java的源碼:
public class UserBalanceServiceImpl implements UserBalanceService { @Autowired private BankService bankService; @Override public Double getAccountBalance(String email) { return Double.valueOf(bankService.getBalanceByEmail(email)); } }
然後是Spring的XML設置裝備擺設文件,添加所須要的bean聲明。
applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="bankService" class="ua.eshepelyuk.blog.springtest.springockito.BankServiceImpl"/> <bean id="userBalanceService" class="ua.eshepelyuk.blog.springtest.springockito.UserBalanceServiceImpl"/> </beans>
上面是測試類UserBalanceServiceImplTest.java的源代碼:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:/springtest/springockito/applicationContext.xml") public class UserBalanceServiceImplProfileTest { @Autowired private UserBalanceService userBalanceService; @Autowired private BankService bankService; @Test public void shouldReturnMockedBalance() { Double balance = userBalanceService.getAccountBalance("[email protected]"); assertEquals(balance, Double.valueOf(123.45D)); } }
如我們預感的一樣,測試辦法報UnsupportedOperationException異常。我們如今的目標是把BankService換成我們的模仿完成。直接應用Mockito來生成factory bean的辦法是沒成績的,然則有更好的選擇,應用Springockito框架。持續之前可以先年夜概懂得一下。
剩下的成績就簡略了:若何讓Spring注入模仿的bean而不是真實的bean,在Spring 3.1版之前除新建一個XML設置裝備擺設文件以外沒有其他的辦法。然則自從Spring引入了bean的profile界說以後,我們有了加倍優雅的處理方法,固然這類方法也須要一個額定的專門用作測試的XML設置裝備擺設文件。上面是這個用來測試的設置裝備擺設文件testApplicationContext.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:mockito="http://www.mockito.org/spring/mockito" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd"> <import resource="classpath:/springtest/springockito/applicationContext.xml"/> <beans profile="springTest"> <mockito:mock id="bankService" class="ua.eshepelyuk.blog.springtest.springockito.BankService"/> </beans> </beans>
做響應修正過以後的測試類UserBalanceServiceImplProfileTest.java的源代碼:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:/springtest/springockito/testApplicationContext.xml") @ActiveProfiles(profiles = {"springTest"}) public class UserBalanceServiceImplProfileTest { @Autowired private UserBalanceService userBalanceService; @Autowired private BankService bankService; @Before public void setUp() throws Exception { Mockito.when(bankService.getBalanceByEmail("[email protected]")).thenReturn(String.valueOf(123.45D)); } @Test public void shouldReturnMockedBalance() { Double balance = userBalanceService.getAccountBalance("[email protected]"); assertEquals(balance, Double.valueOf(123.45D)); } }
你能夠留意到了,在setUp辦法裡,我們界說了模仿的行動,而且在類下面加了@Profile的注解。這個注解激活了名為springTest的profile,是以應用Springockito模仿的bean便可以主動注入就任何它所須要的處所了。這個測試的運轉成果會勝利,由於Spring注入了Springockito 所模仿的版本,而不是applicationContext.xml裡所聲明的版本。
持續優化我們的測試
假如我們能將處理這個成績的辦法加倍推動一步的話,這篇文章看起來才沒出缺憾。Springockito供給了別的一個名字叫作
Springockito Annotation的框架,它許可我們在測試類中應用注解來注入模仿類。持續看下去之前,您最好先去網站上年夜概瞧瞧。好了,上面是經由修正後的測試代碼。
UserBalanceServiceImplAnnotationTest.java的源代碼: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:/springtest/springockito/applicationContext.xml") public class UserBalanceServiceImplAnnotationTest { @Autowired private UserBalanceService userBalanceService; @Autowired @WordStrWithMock private BankService bankService; @Before public void setUp() throws Exception { Mockito.when(bankService.getBalanceByEmail("[email protected]")).thenReturn(String.valueOf(valueOf(123.45D))); } @Test public void shouldReturnMockedBalance() { Double balance = userBalanceService.getAccountBalance("[email protected]"); assertEquals(balance, valueOf(123.45D)); } }
請留意,這裡並沒有新引入的XML設置裝備擺設文件,而是直接應用了正式情況的applicationContext.xml。我們應用@WordStrWithMock這個注解標志了類型為BankService的bean,爾後在setUp辦法中對模仿類的行動停止了界說。
跋文
Springockito-annotations項目有個偉大的長處,那就是,它使我們的測試代碼樹立在依附籠罩的基本之上,經由過程如許,我們既不須要界說額定的XML設置裝備擺設文件,也不須要為了測試而去修改臨盆情況的設置裝備擺設文件。假如不應用Springockito-annotations的話,我們除界說額定的XML設置裝備擺設文件別無他選了。是以,我激烈建議您在集成測試中應用Springockito-annotations,如許你可以最年夜限制削減測試用例對臨盆代碼的影響,也能清除保護額定XML設置裝備擺設文件的累贅。
附言
為Spring工程寫集成測試真是簡略多了吧,文章中的代碼參考自我的GitHub。
譯文鏈接:http://www.codeceo.com/article/spring-test-is-easy.html
英文原文:Test Me If You Can #1 (Spring Framework)
翻譯作者:碼農網 – Sandbox Wang
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。