javascript
spock 集成测试_Spock 1.2 –轻松进行集成测试中的Spring Bean模拟
spock 集成測試
探索如何使用Spock 1.2將Spock的模擬和間諜自動注入到Spring上下文中。
Spock中的存根/模擬/間諜(及其生命周期)一直與Spock Specification類緊密結合。 只能在測試類中創建它們。 因此,使用共享的,預定義的模擬(在單元測試和集成測試中)是有問題的。
這種情況在Spock 1.1中有所改善,但只有在基于Spring的集成測試中使用Spock模擬子系統的全新Spock 1.2(撰寫本文時為1.2-RC1)時,與使用@SpringMock進行Spring @SpringMock一樣容易開機 讓我們檢查一下。
順便說一句,除了Spock 1.2-RC1之外,為了更前沿,我將使用Spring Boot 2.1.0.M2,Spring 5.1.0.RC2和Groovy 2.5.2(但所有功能都應在Spring的穩定版本中使用(引導)和Groovy 2.4)。
還有一件事。 為了簡單起見,在本文中,我將使用術語“模擬”來指代存根和間諜。 它們的行為有所不同 ,但是在Spock測試中將其注入Spring上下文的范圍通常并不重要。
Spock 1.1 –手動方式
多虧了LeonardBrünings的工作,Spock中的模擬才脫離了Specification類。 最終可以在外部創建它們,然后將其附加到正在運行的測試中。 這是在Spring(或任何其他)上下文中使用Spock模擬的基礎。
在此示例代碼中,我們有ShipDatabase類,該類使用OwnShipIndex和EnemyShipIndex (當然是由構造函數注入的:))來返回有關所有與名稱匹配的已知船只的匯總信息。
//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests //Real beans can exist in the context or not @ContextConfiguration(classes = [ShipDatabase, TestConfig/*, OwnShipIndex, EnemyShipIndex*/]) class ShipDatabase11ITSpec extends Specification {private static final String ENTERPRISE_D = "USS Enterprise (NCC-1701-D)"private static final String BORTAS_ENTERA = "IKS Bortas Entera"@Autowiredprivate OwnShipIndex ownShipIndexMock@Autowiredprivate EnemyShipIndex enemyShipIndexMock@Autowiredprivate ShipDatabase shipDatabasedef "should find ship in both indexes"() {given:ownShipIndexMock.findByName("Enter") >> [ENTERPRISE_D]enemyShipIndexMock.findByName("Enter") >> [BORTAS_ENTERA]when:List<String> foundShips = shipDatabase.findByName("Enter")then:foundShips == [ENTERPRISE_D, BORTAS_ENTERA]}static class TestConfig {private DetachedMockFactory detachedMockFactory = new DetachedMockFactory()@Bean@Primary //if needed, beware of consequencesOwnShipIndex ownShipIndexStub() {return detachedMockFactory.Stub(OwnShipIndex)}@Bean@Primary //if needed, beware of consequencesEnemyShipIndex enemyShipIndexStub() {return detachedMockFactory.Stub(EnemyShipIndex)}} }這些模擬是在單獨的類中(在Specification之外)創建的,因此必須使用DetachedMockFactory (或使用SpockMockFactoryBean )。 這些模擬必須被附加(和分離)到測試實例( Specification實例),但是由spock-spring模塊(從1.1版本開始)會自動處理。 對于從外部創建的通用MockUtil.attachMock() ,還需要使用MockUtil.attachMock()和mockUtil.detachMock()使其起作用。
結果,可以在Spring上下文中創建和使用模擬,但是它不是很方便,也不常用。
Spock 1.2 –一流的支持
Spring Boot 1.4通過(Mockito)的模擬為集成測試帶來了新的質量。 它利用了最初于2012年在Springockito中提出的想法(當時Spring配置主要是用XML編寫的:))將模擬(或間諜)自動注入到Spring(引導)上下文中。 Spring Boot團隊擴展了這個想法,并且由于有了它作為內部支持的功能(通常),因此只需在測試中添加一個或兩個注釋即可可靠地工作。
Spock 1.2中內置了類似的基于注釋的機制。
//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests //Real beans can exist in the context or not @ContextConfiguration(classes = [ShipDatabase/*, OwnShipIndex, EnemyShipIndex*/]) class ShipDatabaseITSpec extends Specification {private static final String ENTERPRISE_D = "USS Enterprise (NCC-1701-D)"private static final String BORTAS_ENTERA = "IKS Bortas Entera"@SpringBeanprivate OwnShipIndex ownShipIndexMock = Stub() //could be Mock() if needed@SpringBeanprivate EnemyShipIndex enemyShipIndexMock = Stub()@Autowiredprivate ShipDatabase shipDatabasedef "should find ship in both indexes"() {given:ownShipIndexMock.findByName("Enter") >> [ENTERPRISE_D]enemyShipIndexMock.findByName("Enter") >> [BORTAS_ENTERA]when:List<String> foundShips = shipDatabase.findByName("Enter")then:foundShips == [ENTERPRISE_D, BORTAS_ENTERA]} }沒有太多要添加的內容。 @SpringBean指示Spock將模擬注入到Spring上下文中。 類似地, @SpringSpy用間諜包裝真實的bean。 在@SpringBean的情況下,需要初始化一個字段以讓Spock知道我們打算使用存根還是模擬。
另外,還有一個更通用的注釋@StubBeans ,以存根替換所有已定義的bean。 但是,我計劃在另一篇博客文章中單獨介紹它。
局限性
對于那些希望在本文演講后立即在您的Spock測試中將所有Mockito的模擬重寫為Spock的模擬的人來說,這是一個警告。 Spock的模擬物-由于其性質和與Specification關系-具有某些局限性。 在幕后的實現創建了一個代理,該代理被注入到Spring上下文中(可能)替換實際的bean(存根/模擬)或包裝它們(間諜)。 該代理在特定測試(規范)類中的所有測試之間共享。 實際上,在Spring能夠緩存上下文的情況下,它也可以跨越具有相同bean / mock聲明的其他測試(與Mockito的模擬或一般的Spring集成測試類似的情況)。
但是,真正重要的是,代理在執行之前就已連接到測試,并在執行之后被分離。 因此,實際上,每個測試都有其自己的模擬實例(不能應用于@Shared字段),例如,將來自不同測試的交互分組并一起驗證它們是有問題的(通常是非常明智的,但可能會導致某些情況)復制)。 但是,使用setup塊(或在線存根)可以共享存根和交互預期。
摘要
Spock 1.2最終帶來了輕松的Spock存根/模擬/間諜支持,以便在Spring上下文中使用它們,這與Spring Boot中為Mockito提供的支持相當。 將spock-spring模塊添加到項目(運行時)依賴項就足夠了。 盡管有一些限制,但在Spock(集成)測試中將本機Spock的模擬子系統與外部模擬框架(例如Mockito)混合起來要少一點。 不錯的是,它也應該在普通的Spring Framework測試中起作用(不僅是Spring Boot測試)。 Guice已實現了相同的功能(但我尚未對其進行測試)。
此外,Spock 1.2還帶來了其他一些更改,包括對Java 9+的更好支持,值得在您的測試套件中進行嘗試(當然,請報告任何可能發現的回歸錯誤:))。
還有一個好消息。 除了使Spock 1.2成為可能的倫納德的工作以及大量的錯誤報告者和PR貢獻者之外,最近以來,還有其他一些提交者正在致力于使Spock變得更好。 您可能從其他一些流行的FOSS項目中了解了其中一些。 而且,Spock 1.2 (初步)計劃成為基于JUnit 4的最后一個版本,而下一個穩定的Spock版本可能是2.0,這是利用JUnit 5及其(以及其他)并行運行測試的本機能力。
這些示例是使用Spock 1.2-RC1編寫的。 一旦發布,它將更新為1.2-final。 源代碼可從GitHub獲得。
翻譯自: https://www.javacodegeeks.com/2018/09/spock-spring-beans-mocking-integration.html
spock 集成測試
總結
以上是生活随笔為你收集整理的spock 集成测试_Spock 1.2 –轻松进行集成测试中的Spring Bean模拟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谁可以打败如来佛祖(鸿钧老祖与如来谁厉)
- 下一篇: 买整机能不能超频怎么超?看完你就懂了