欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Spock框架Mock對象的方法經(jīng)驗總結(jié)

 更新時間:2022年02月23日 14:31:08   作者:FunTester  
這篇文章主要分享了Spock框架Mock對象的方法經(jīng)驗總結(jié),下文分享一些常用項目實戰(zhàn)說明以及代碼,供大家項目中參考,也具有一的的參考價值,需要的小伙伴可以參考一下

前言:

下面分享一些使用過的一個常用項目,部分信息隱去了。大家在自己項目中實踐的時候可以參考,盡量別直接抄代碼,我自己使用過程中有很多兼容性的坑,特別是IDE自動import功能。

一、技術(shù)方案

本技術(shù)方案基于公司力推的Spock單元測試框架,spock是一款基于Groovy語言的單元測試框架,其基礎(chǔ)也是Java的Junit,目前最新版已經(jīng)到了2.0,但對Groovy和相應的Java版本要求較高,所以Groovy版本使用1.+,Spock自帶的Mock和Spy足夠好了,對于對象行為的模擬滿足絕大部分場景,但是涉及靜態(tài)方法模擬時候存在局限性,所以引入MockitoPowerMock來實現(xiàn)設計靜態(tài)方法的測試模擬場景。

以下為相關(guān)依賴版本:     

 ? <dependency>
? ? ? ? ? ? <groupId>org.spockframework</groupId>
? ? ? ? ? ? <artifactId>spock-core</artifactId>
? ? ? ? ? ? <version>1.2-groovy-2.5</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.spockframework</groupId>
? ? ? ? ? ? <artifactId>spock-spring</artifactId>
? ? ? ? ? ? <version>1.2-groovy-2.5</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>

? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.powermock</groupId>
? ? ? ? ? ? <artifactId>powermock-api-mockito2</artifactId>
? ? ? ? ? ? <version>1.7.4</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.mockito</groupId>
? ? ? ? ? ? <artifactId>mockito-core</artifactId>
? ? ? ? ? ? <version>2.8.9</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>

因為Spock本身需要Groovy語言支持,所以也需要一個Groovy-all的依賴,請注意注自帶的注釋:

? ? ? <dependency> <!-- use a specific Groovy version rather than the one specified by spock-core -->
? ? ? ? ? ? <groupId>org.codehaus.groovy</groupId>
? ? ? ? ? ? <artifactId>groovy-all</artifactId>
? ? ? ? ? ? <version>2.4.7</version>
? ? ? ? </dependency>

另外,提供的配置文件中多了幾項特殊場景下使用的依賴,提供參考:

 ? <dependency> <!-- enables mocking of classes (in addition to interfaces) -->
? ? ? ? ? ? <groupId>net.bytebuddy</groupId>
? ? ? ? ? ? <artifactId>byte-buddy</artifactId>
? ? ? ? ? ? <version>1.9.9</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>
? ? ? ? <dependency> <!-- enables mocking of classes without default constructor (together with CGLIB) -->
? ? ? ? ? ? <groupId>org.objenesis</groupId>
? ? ? ? ? ? <artifactId>objenesis</artifactId>
? ? ? ? ? ? <version>3.0.1</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>
? ? ? ? <dependency> <!-- only required if Hamcrest matchers are used -->
? ? ? ? ? ? <groupId>org.hamcrest</groupId>
? ? ? ? ? ? <artifactId>hamcrest-core</artifactId>
? ? ? ? ? ? <version>2.1</version>
? ? ? ? ? ? <scope>test</scope>
? ? ? ? </dependency>

二、非靜態(tài)資源

由于多個單測框架的方法名重復較多,我把import內(nèi)容也貼出來了,如果同樣的代碼無法運行,可以排查一下是否import正確的方法和類。這里不是很建議import static ,因為可能出現(xiàn)混用以及不易排查的問題。

由于目前測試中沒有遇到使用Spy放行的邏輯,所以均使用Mock模式,需要對Mock對象的方法進行模擬。這個分為兩類:Spock和PowerMock(結(jié)合Mockito)。原因是在混合靜態(tài)資源和非靜態(tài)資源場景下,指定了PowerMock@RunWith運行規(guī)則,不兼容Spock寫法,需要用到PowerMock框架Mock對象的功能。

三、Mock被測對象

1.@Autowired構(gòu)造方法

用一個controller舉例,源代碼如下:

@Api(tags = "SLA規(guī)則管理模塊")
@Slf4j
@RestController
@RequestMapping("/hickwall/v1/static/sla")
public class FunController {

? ? HttpServletRequest request;

? ? ISlaService service;

? ? @Autowired
? ? public FunController(HttpServletRequest request, ISlaService service) {
? ? ? ? this.request = request;
? ? ? ? this.service = service;
? ? }

}

Spock單測代碼如下:

import com.funtester.service.ISlaService
import com.funtester.vo.sla.SlaBean
import spock.lang.Shared
import spock.lang.Specification

import javax.servlet.http.HttpServletRequest

class FunControllerTest extends Specification {

? ? def service = Mock(ISlaService)

? ? @Shared
? ? def request = Mock(HttpServletRequest)
? ??
? ? def FunController = new FunController(request, service)

}

2.@Autowired屬性對象,無構(gòu)造方法

源代碼如下:

public class ApiImpl implements IApi {

? ? @Autowired
? ? private ApiRMapper mapper;
}

Spock單測部分代碼如下:

import com.funtester.mapper.ApiRMapper
import com.funtester.vo.ApiR
import spock.lang.Shared
import spock.lang.Specification


? ? ApiRMapper mapper = Mock(ApiRMapper)

? ? def drive = new ApiImpl(mapper:mapper)

3.PowerMock用法

場景也分為兩種:有無構(gòu)造方法,除了Mock方法不同以外,其他均相同,這里不列舉。

PS:如果對象屬性中有未被@Autowired注釋的屬性,不能用@AllArgsConstructor的lombok注解,服務啟動會報錯。

源代碼如下:

@Component
@Slf4j
public class TaskScheduled {

? ? @Autowired
? ? IService service;
? ??
? ? @Value("${hickwall.statistic.cid}")
? ? public ?String cid;

}

4.共享對象以及初始化

統(tǒng)一使用Spock提供的功能,用到的注解@Shared,不加的話無法在Spock方法中進行賦值操作,但是可以當做一個普通的對象使用。

Spock框架Demo:

? ? @Shared
? ? def slaBean = new SlaBean()

? ? def setupSpec() {
? ? ? ? request.getHeader("operator") >> "FunTester"
? ? ? ? slaBean.name = "測試"
? ? ? ? slaBean.quota = 1
? ? ? ? slaBean.upstream = "PRO"
? ? ? ? slaBean.threshold = 0.1
? ? ? ? slaBean.creator = "FunTester"
? ? ? ? slaBean.id = 100
? ? }

四、定義對象行為

1.Spock定義Mock對象行為

基礎(chǔ)的Spock語法結(jié)構(gòu)when-then-expct如下:

? ? def "AddSla"() {
? ? ? ? when:
? ? ? ? def sla = FunController.addSla(slaBean)
? ? ? ? then:
? ? ? ? service.addSla(_) >> {f ->
? ? ? ? ? ? assert "FunTester" in f.creator
? ? ? ? ? ? 1
? ? ? ? }

? ? ? ? expect:

? ? ? ? sla.code == 0
? ? ? ? sla.data == 1

? ? }

也可以在最開始加上given,whenthen通常一起使用。

上述Demo在Mock方法的時候?qū)?shù)進行了斷言和處理,這也是Spock框架的一個特性,其他均為Groovy語法特性。

其他定義Mock行為的語法如下:

 ? service.getAllGroup(_,_) >> null//返回null
? ? ? ? service.getAllGroup(_,_) >> {throw new Exception()} //拋出異常
? ? ? ? service.getAllGroup(_,_) >> []//返回空list,Groovy默認實現(xiàn)ArrayList
? ? ? ? service.getAllGroup(_,_) >> [slaBean,slaBean]//返回正常list
? ? ? ? service.getAllGroup(_,_) >> [slaBean,slaBean]//返回正常list
? ? ? ? service.getAllGroup(_,10) >> [slaBean,slaBean]//定時某個參數(shù)
? ? ? ? service.getAllGroup(any(),10) >> [slaBean,slaBean]//any()等效于_
? ? ? ? service.getAllGroup(any(),10) >> service.getAllGroup(1,10)//調(diào)用其他方法返回

2.Mockito模擬對象行為

MockitoPowerMock配合使用語法稍微復雜一些。首先我們需要先定義對象行為(通常在com.funtesterbase.task.TaskScheduledTest#setupSpec方法中),然后在用例用使用。

定時對象行為:

? ? ? ? Mockito.when(newutil.filter(Mockito.any())).thenReturn(true)

定義行為以后,就可以在Spock用例中正常使用,包括在通過Mock對象創(chuàng)建的對象方法中,如果調(diào)用到定義過行為的方法,也會走自定義的邏輯。

其他常用定義行為:

? ? ? ? Mockito.when(newutil.filter(Mockito.any())).thenReturn(null)
? ? ? ? Mockito.when(newutil.filter(Mockito.any())).thenThrow(Exception.class)//拋出異常
? ? ? ? PowerMockito.doNothing().when(newutil).filter(Mockito.any(ArrayList.class))//dothing,什么都不做

第三個例子中我們假設filter方法是一個無返回的void方法。

通常我們需要構(gòu)建返回對象,如果對象需要賦值的屬性過多,可以使用初始化賦值的方法,下面是Mock一個返回list的方法返回值的Demo:

Mockito.when(newser.selectAllService()).thenReturn([new NewInterface() {

? ? ? ? ? ? {
? ? ? ? ? ? ? ? setUrl("/abc")
? ? ? ? ? ? ? ? setNname("test TGFC z;/./")
? ? ? ? ? ? ? ? setMethod("GET")
? ? ? ? ? ? }
? ? ? ? }, new NewInterface() {

? ? ? ? ? ? {
? ? ? ? ? ? ? ? setUrl("/abcd")
? ? ? ? ? ? ? ? setNname("test")
? ? ? ? ? ? ? ? setMethod("POST")
? ? ? ? ? ? }
? ? ? ? }, new NewInterface() {

? ? ? ? ? ? {
? ? ? ? ? ? ? ? setUrl("/abce")
? ? ? ? ? ? ? ? setNname("test")
? ? ? ? ? ? ? ? setMethod("GET")
? ? ? ? ? ? }
? ? ? ? }])

到此這篇關(guān)于Spock框架Mock對象的方法經(jīng)驗總結(jié)的文章就介紹到這了,更多相關(guān)Spock框架Mock對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的SPI機制實例詳解

    Java的SPI機制實例詳解

    這篇文章主要介紹了Java的SPI機制實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java圖形界面超實用使用教程

    Java圖形界面超實用使用教程

    在Java編程中圖形界面應用程序是非常常見和重要的一部分,下面這篇文章主要給大家介紹了關(guān)于Java圖形界面的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • IDEA 自定義方法注解模板的實現(xiàn)方法

    IDEA 自定義方法注解模板的實現(xiàn)方法

    這篇文章主要介紹了IDEA 自定義方法注解模板的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • spring結(jié)合struts的代碼詳解

    spring結(jié)合struts的代碼詳解

    這篇文章主要介紹了spring結(jié)合struts的代碼詳解,需要的朋友可以參考下
    2017-09-09
  • Java基于堆結(jié)構(gòu)實現(xiàn)優(yōu)先隊列功能示例

    Java基于堆結(jié)構(gòu)實現(xiàn)優(yōu)先隊列功能示例

    這篇文章主要介紹了Java基于堆結(jié)構(gòu)實現(xiàn)優(yōu)先隊列功能,結(jié)合實例形式分析了java優(yōu)先隊列的簡單定義與使用方法,需要的朋友可以參考下
    2017-11-11
  • java 如何實現(xiàn)多語言配置i18n

    java 如何實現(xiàn)多語言配置i18n

    這篇文章主要介紹了java 如何實現(xiàn)多語言配置i18n的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot邏輯異常統(tǒng)一處理方法

    SpringBoot邏輯異常統(tǒng)一處理方法

    這篇文章主要介紹了SpringBoot邏輯異常統(tǒng)一處理方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 一文帶你真正理解Java中的內(nèi)部類

    一文帶你真正理解Java中的內(nèi)部類

    不知道大家在平時的開發(fā)過程中或者源碼里是否留意過內(nèi)部類,那有思考過為什么要有內(nèi)部類,內(nèi)部類都有哪幾種形式,本篇文章主要帶領(lǐng)大家理解下這塊內(nèi)容
    2022-08-08
  • 詳述IntelliJ IDEA插件的安裝及使用方法(圖解)

    詳述IntelliJ IDEA插件的安裝及使用方法(圖解)

    本篇文章主要介紹了詳述 IntelliJ IDEA 插件的安裝及使用方法(圖解),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Spring中的BeanFactory工廠詳細解析

    Spring中的BeanFactory工廠詳細解析

    這篇文章主要介紹了Spring中的BeanFactory工廠詳細解析,Spring的本質(zhì)是一個bean工廠(beanFactory)或者說bean容器,它按照我們的要求,生產(chǎn)我們需要的各種各樣的bean,提供給我們使用,需要的朋友可以參考下
    2023-12-12

最新評論