最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring測試 其實很簡單

 更新時間:2016年07月08日 16:41:07   作者:Sandbox Wang  
這篇文章主要為大家詳細(xì)介紹了Spring測試,其實很簡單,揭開集成測試神秘的面紗,感興趣的小伙伴們可以參考一下

在過去的職業(yè)生涯里,我經(jīng)常發(fā)現(xiàn)有些人不寫測試代碼,而他們聲稱不寫的理由是無法輕易地寫出覆蓋多個不同模塊的測試用例。好吧,我相信他們中的大部分要么是缺乏一些比較易掌握的技術(shù)手段,要么就是沒時間來把它搞清楚,畢竟工作中總會有進(jìn)度之類的各種壓力。因為不知道該如何測試,所以就經(jīng)常忽略集成測試,由此帶來的問題就是越來越糟糕的軟件、越來越多的BUG和更加失望的客戶。所以我想分享一些個人的經(jīng)驗,揭開集成測試神秘的面紗。 

如何對基于Spring的工程更好地進(jìn)行集成測試
使用工具: Spring, JUnit, Mockito
想象有這樣一個Spring工程,它集成了一些外部服務(wù),例如,一些銀行的web服務(wù)。那么,為這個工程寫測試用例以及在持續(xù)集成系統(tǒng)中完成這些測試時所遇到的問題基本都差不多:
 1.每次測試都會有交易進(jìn)行,每次交易都需要付出金錢成本,這些成本最終由客戶承擔(dān);
 2.測試時發(fā)出的過多的請求有可能被認(rèn)為是惡意請求,可能造成在銀行的賬戶被封,后果是測試失??;
 3.當(dāng)使用非生產(chǎn)環(huán)境進(jìn)行測試時,測試結(jié)果并不十分可靠,同樣,后果是測試失敗。
通常情況下,你對單個類進(jìn)行測試的時候,問題很容易解決,因為你可以虛擬一些外部服務(wù)來供調(diào)用。但是當(dāng)對整個巨大的業(yè)務(wù)流程進(jìn)行測試的時候,意味你需要對多個部件進(jìn)行測試,這時,需要你將這些部件都納入到Spring容器中進(jìn)行管理。所幸,Spring包含了非常優(yōu)秀的測試框架,允許你將來自生產(chǎn)環(huán)境配置文件中的bean注入到測試環(huán)境中,但是對那些被調(diào)用的外部服務(wù),需要我們自己去寫模擬實現(xiàn)。一般人第一反應(yīng)可能是在測試的setUp階段對由Spring注入的bean進(jìn)行重新注入(修改),但是這種方法需要再仔細(xì)考慮一下。 

警告:通過這種方式,你的測試代碼打破了容器自身的行為,所以沒法保證在真實的環(huán)境中也如你測試的結(jié)果一樣。
事實上,我們無需先實現(xiàn)模擬類然后再把它重新注入到所需的bean中,我們可以讓Spring幫助我們一開始就注入模擬類。讓我們用代碼演示一下。
示例工程包含一個名為BankService的類,代表調(diào)用的外部服務(wù),一個名為UserBalanceService的類,它會調(diào)用BankService。UserBalanceService實現(xiàn)的非常簡單,僅僅完成將余額從String向Double類型的轉(zhuǎn)換。
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("user@bank.com");
  assertEquals(balance, Double.valueOf(123.45D));
 }
} 

如我們預(yù)料的一樣,測試方法報UnsupportedOperationException異常。我們現(xiàn)在的目的是把BankService換成我們的模擬實現(xiàn)。直接使用Mockito來生成factory bean的方法是沒問題的,但是有更好的選擇,使用Springockito框架。繼續(xù)之前可以先大概了解一下。 

剩下的問題就簡單了:如何讓Spring注入模擬的bean而不是真實的bean,在Spring 3.1版之前除了新建一個XML配置文件之外沒有其他的方法。但是自從Spring引入了bean的profile定義之后,我們有了更加優(yōu)雅的解決方式,雖然這種方式也需要一個額外的專門用作測試的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> 

做相應(yīng)修改過之后的測試類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("user@bank.com")).thenReturn(String.valueOf(123.45D));
 }
 @Test
 public void shouldReturnMockedBalance() {
  Double balance = userBalanceService.getAccountBalance("user@bank.com");
  assertEquals(balance, Double.valueOf(123.45D));
 }
} 

你可能注意到了,在setUp方法里,我們定義了模擬的行為,并且在類上面加了@Profile的注解。這個注解激活了名為springTest的profile,因此使用Springockito模擬的bean就可以自動注入到任何它所需要的地方了。這個測試的運(yùn)行結(jié)果會成功,因為Spring注入了Springockito 所模擬的版本,而不是applicationContext.xml里所聲明的版本。

繼續(xù)優(yōu)化我們的測試
 如果我們能將解決這個問題的方法更加推進(jìn)一步的話,這篇文章看起來才沒有缺憾。Springockito提供了另外一個名字叫作
 Springockito Annotation的框架,它允許我們在測試類中使用注解來注入模擬類。繼續(xù)看下去之前,您最好先去網(wǎng)站上大概瞧瞧。好了,下面是經(jīng)過修改后的測試代碼。

 UserBalanceServiceImplAnnotationTest.java的源代碼:
 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class,
 locations = "classpath:/springtest/springockito/applicationContext.xml")
public class UserBalanceServiceImplAnnotationTest {
 @Autowired
 private UserBalanceService userBalanceService;
 @Autowired
 @ReplaceWithMock
 private BankService bankService;
 @Before
 public void setUp() throws Exception {
  Mockito.when(bankService.getBalanceByEmail("user@bank.com")).thenReturn(String.valueOf(valueOf(123.45D)));
 }
 @Test
 public void shouldReturnMockedBalance() {
  Double balance = userBalanceService.getAccountBalance("user@bank.com");
  assertEquals(balance, valueOf(123.45D));
 }
} 

請注意,這里并沒有新引入的XML配置文件,而是直接使用了正式環(huán)境的applicationContext.xml。我們使用@ReplaceWithMock這個注解標(biāo)記了類型為BankService的bean,而后在setUp方法中對模擬類的行為進(jìn)行了定義。

后記
Springockito-annotations項目有個巨大的優(yōu)點(diǎn),那就是,它使我們的測試代碼建立在依賴覆蓋的基礎(chǔ)之上,通過這樣,我們既不需要定義額外的XML配置文件,也不需要為了測試而去改動生產(chǎn)環(huán)境的配置文件。如果不使用Springockito-annotations的話,我們除了定義額外的XML配置文件別無他選了。因此,我強(qiáng)烈建議您在集成測試中使用Springockito-annotations,這樣你可以最大限度減少測試用例對生產(chǎn)代碼的影響,也能消除維護(hù)額外XML配置文件的負(fù)擔(dān)。
附言
為Spring工程寫集成測試真是簡單多了吧,文章中的代碼參考自我的GitHub。 

譯文鏈接:http://www.codeceo.com/article/spring-test-is-easy.html
英文原文:Test Me If You Can #1 (Spring Framework)
翻譯作者:碼農(nóng)網(wǎng) – Sandbox Wang

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA中Collections.sort()方法使用詳解

    JAVA中Collections.sort()方法使用詳解

    這篇文章主要給大家介紹了關(guān)于JAVA中Collections.sort()方法使用的相關(guān)資料,Java中Collections.sort()方法是用來對List類型進(jìn)行排序的,文中通過代碼將使用的方法介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • MyBatis-Plus數(shù)據(jù)庫配置與數(shù)據(jù)源整合方案

    MyBatis-Plus數(shù)據(jù)庫配置與數(shù)據(jù)源整合方案

    本文詳細(xì)介紹了在MyBatis-Plus中進(jìn)行數(shù)據(jù)庫配置與數(shù)據(jù)源整合的常見方法,包括單數(shù)據(jù)源和多數(shù)據(jù)源的配置步驟,以及如何使用SpringBoot的自動配置和手動配置來管理數(shù)據(jù)源,通過合理的配置,開發(fā)者可以簡化數(shù)據(jù)庫操作,實現(xiàn)高效的數(shù)據(jù)庫管理和復(fù)雜的應(yīng)用架構(gòu)
    2025-02-02
  • 詳解Java中信號量Semaphore的使用

    詳解Java中信號量Semaphore的使用

    在Java中,正確地管理并發(fā)是一件既挑戰(zhàn)又有趣的事情,當(dāng)談到并發(fā)控制,就不得不說Java中的一個非常強(qiáng)大的工具,就是Semaphore,下面我們就來看看Java中信號量Semaphore的具體使用吧
    2024-01-01
  • JAVA中4種解析XML文件的方法

    JAVA中4種解析XML文件的方法

    這篇文章主要介紹了JAVA中4種解析XML文件的方法,文中示例代碼非常詳細(xì),幫助大家更好的了解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • SpringBoot實現(xiàn)快遞物流查詢功能(快遞鳥)

    SpringBoot實現(xiàn)快遞物流查詢功能(快遞鳥)

    本文將基于springboot2.4.0實現(xiàn)快遞物流查詢,物流信息的獲取通過快遞鳥第三方實現(xiàn),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-10-10
  • JAVA自定義注解詳情

    JAVA自定義注解詳情

    這篇文章主要介紹了Java自定義注解,結(jié)合實例形式總結(jié)分析了java常見的自定義注解類型、功能、用法及操作注意事項,需要的朋友可以參考下
    2021-10-10
  • 詳解SpringBoot中@PostMapping注解的用法

    詳解SpringBoot中@PostMapping注解的用法

    在SpringBoot中,我們經(jīng)常需要編寫RESTful Web服務(wù),以便于客戶端與服務(wù)器之間的通信,@PostMapping注解可以讓我們更方便地編寫POST請求處理方法,在本文中,我們將介紹@PostMapping注解的作用、原理,以及如何在SpringBoot應(yīng)用程序中使用它
    2023-06-06
  • Java中Object類常用的12個方法(小結(jié))

    Java中Object類常用的12個方法(小結(jié))

    Java 中的 Object 方法在面試中是一個非常高頻的點(diǎn),本文主要介紹了Java中Object類常用的12個方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • IntelliJ?IDEA?2022.1.1創(chuàng)建java項目的詳細(xì)方法步驟

    IntelliJ?IDEA?2022.1.1創(chuàng)建java項目的詳細(xì)方法步驟

    最近安裝了IntelliJ IDEA 2022.1.1,發(fā)現(xiàn)新版本的窗口還有些變化的,所以下面這篇文章主要給大家介紹了關(guān)于IntelliJ?IDEA?2022.1.1創(chuàng)建java項目的詳細(xì)方法步驟,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • java 算法之歸并排序詳解及實現(xiàn)代碼

    java 算法之歸并排序詳解及實現(xiàn)代碼

    這篇文章主要介紹了java 算法之歸并排序詳解及實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03

最新評論

广宁县| 宁都县| 舟曲县| 雷山县| 深州市| 南投市| 大同县| 读书| 东丽区| 阜南县| 棋牌| 且末县| 廉江市| 临夏县| 资兴市| 青铜峡市| 怀来县| 陆丰市| 十堰市| 嘉荫县| 阳山县| 城固县| 铁岭县| 嘉兴市| 孝昌县| 裕民县| 宁都县| 东丰县| 武强县| 航空| 阜康市| 潜江市| 龙泉市| 阜南县| 宣威市| 红河县| 沙洋县| 南丰县| 巍山| 曲周县| 巴楚县|