日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

如何在没有Springockito的情况下模拟Spring bean

發布時間:2023/12/3 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在没有Springockito的情况下模拟Spring bean 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我在Spring工作了幾年。 但是我總是對XML配置變得多么混亂感到沮喪。 隨著各種注釋和Java配置可能性的出現,我開始喜歡使用Spring進行編程。 這就是為什么我強烈使用Java配置的原因。 我認為,僅當您需要可視化Spring Integration或Spring Batch流時,XML配置才適用。 希望Spring Tool Suite還將能夠可視化這些框架的Java配置。

XML配置的令人討厭的方面之一是,它通常會導致龐大的XML配置文件。 因此,開發人員經常創建用于集成測試的測試上下文配置。 但是,如果不對生產布線進行測試,那么集成測試的目的是什么? 這樣的集成測試幾乎沒有價值。 因此,我一直試圖以可測試的方式設計生產環境。

我除了在創建新項目/模塊時會盡可能避免XML配置。 因此,使用Java配置,您可以為每個模塊/包創建Spring配置,并在主上下文中對其進行掃描(@Configuration也是組件掃描的候選者)。 這樣,您可以自然地創建島嶼Spring bean。 這些島可以很容易地進行隔離測試。

但是我必須承認,并非總是可以按原樣測試生產Java配置。 很少需要修改某些豆的行為或監視。 有一個名為Springockito的庫。 老實說,到目前為止,我還沒有使用過它,因為我總是嘗試設計Spring配置以避免進行模擬。 縱觀Springockito的發展速度和未解決的問題數量 ,我有點擔心將其引入我的測試套件堆棧中。 實際上,最后一個發行版是在Spring 4發行版之前完成的,帶來了諸如“是否可以輕松地將其與Spring 4集成?”之類的問題。 我不知道,因為我沒有嘗試過。 如果需要在集成測試中模擬Spring bean,我更喜歡純Spring方法。

Spring提供了@Primary批注,用于指定在注冊了兩個相同類型的bean時首選哪個bean。 這很方便,因為您可以在集成測試中用偽造的Bean覆蓋生產Bean。 讓我們探索這種方法,并舉例說明一些陷阱。

我選擇了這種簡單/虛擬的生產代碼結構進行演示:

@Repository public class AddressDao {public String readAddress(String userName) {return "3 Dark Corner";} }@Service public class AddressService {private AddressDao addressDao;@Autowiredpublic AddressService(AddressDao addressDao) {this.addressDao = addressDao;}public String getAddressForUser(String userName){return addressDao.readAddress(userName);} }@Service public class UserService {private AddressService addressService;@Autowiredpublic UserService(AddressService addressService) {this.addressService = addressService;}public String getUserDetails(String userName){String address = addressService.getAddressForUser(userName);return String.format("User %s, %s", userName, address);} }

AddressDao單例bean實例注入到AddressServiceAddressServiceUserService也類似使用。

我必須在此階段警告您。 我的方法對生產代碼略有侵入。 為了能夠偽造現有的生產Bean,我們必須在集成測試中注冊偽造的Bean。 但是這些假bean通常與生產bean位于同一包子樹中(假設您使用的是標準Maven文件結構:“ src / main / java”和“ src / test / java”)。 因此,當它們在同一包子樹中時,將在集成測試期間對其進行掃描。 但是我們不想在所有集成測試中都使用所有bean的假貨。 偽造品可能會破壞無關的集成測試。 因此,我們需要一種機制,如何告訴測試僅使用某些假豆。 這是通過從組件掃描中完全排除假豆來完成的。 集成測試明確定義了正在使用的偽造品(稍后將顯示)。 現在讓我們看一下從組件掃描中排除假豆的機制。 我們定義了自己的標記注釋:

public @interface BeanMock { }

并在主要的Spring配置中從組件掃描中排除@BeanMock批注。

@Configuration @ComponentScan(excludeFilters = @Filter(BeanMock.class)) @EnableAutoConfiguration public class Application { }

組件掃描的根包是Application類的當前包。 因此,所有上述生產Bean都必須位于同一包裝或子包裝中。 現在,我們需要為UserService創建集成測試。 讓我們窺探地址服務bean。 當然,使用此生產代碼進行此類測試沒有實際意義,但這僅是示例。 這是我們的間諜豆:

@Configuration @BeanMock public class AddressServiceSpy {@Bean@Primarypublic AddressService registerAddressServiceSpy(AddressService addressService) {return spy(addressService);} }

生產AddressService bean是從生產上下文自動連接的,包裝到Mockito的間諜中,并注冊為AddressService類型的主bean。 @Primary批注確保我們的假bean將用于集成測試而不是生產bean。 @BeanMock批注可確保Application組件掃描無法掃描此bean。 現在讓我們看一下集成測試:

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { Application.class, AddressServiceSpy.class }) public class UserServiceITest {@Autowiredprivate UserService userService;@Autowiredprivate AddressService addressService;@Testpublic void testGetUserDetails() {// GIVEN - spring context defined by Application class// WHENString actualUserDetails = userService.getUserDetails("john");// THENAssert.assertEquals("User john, 3 Dark Corner", actualUserDetails);verify(addressService, times(1)).getAddressForUser("john");} }

@SpringApplicationConfigration批注具有兩個參數。 首先( Application.class )聲明受測的Spring配置。 第二個參數( AddressServiceSpy.class )指定將用于測試的假bean加載到Spring IoC容器中。 顯然,我們可以根據需要使用盡可能多的bean偽造品, 但是您不想擁有太多的bean偽造品。 這種方法應該很少使用,如果您經常觀察自己使用這種模擬,那么您的應用程序或開發團隊中的緊密耦合可能會遇到嚴重的問題。 TDD方法論應該可以幫助您解決此問題。 請記住:“減少嘲笑總是更好!”。 因此,請考慮進行生產設計更改,以減少模擬的使用。 這也適用于單元測試。

在集成測試中,我們可以自動連接此間諜bean并將其用于各種驗證。 在這種情況下,我們驗證了測試方法userService.getUserDetails addressService.getAddressForUser使用參數“ john”調用了方法addressService.getAddressForUser

我再舉一個例子。 在這種情況下,我們不會監視生產bean。 我們將模擬它:

@Configuration @BeanMock public class AddressDaoMock {@Bean@Primarypublic AddressDao registerAddressDaoMock() {return mock(AddressDao.class);} }

再次,我們重寫了生產bean,但是這次我們用Mockito的模擬代替它。 然后,我們可以在集成測試中記錄模擬行為:

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = { Application.class, AddressDaoMock.class }) public class AddressServiceITest {@Autowiredprivate AddressService addressService;@Autowiredprivate AddressDao addressDao;@Testpublic void testGetAddressForUser() {// GIVENwhen(addressDao.readAddress("john")).thenReturn("5 Bright Corner");// WHENString actualAddress = addressService.getAddressForUser("john");// THENAssert.assertEquals("5 Bright Corner", actualAddress);}@Afterpublic void resetMock() {reset(addressDao);} }

我們通過@SpringApplicationConfiguration的參數加載@SpringApplicationConfiguration的bean。 在測試方法中,當將“ john”作為參數傳遞給它時,將存根addressDao.readAddress方法以返回“ 5 Bright Corner”字符串。

但是請記住,記錄的行為可以通過Spring上下文進行不同的集成測試。 我們不希望測試相互影響。 因此,您可以通過在測試后重置模擬來避免測試套件中將來出現問題。 這是在方法resetMock完成的。

  • 源代碼在Github上 。

翻譯自: https://www.javacodegeeks.com/2014/12/how-to-mock-spring-bean-without-springockito.html

總結

以上是生活随笔為你收集整理的如何在没有Springockito的情况下模拟Spring bean的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。