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

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

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

前言:

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

一、技術(shù)方案

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

以下為相關(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>

因?yàn)?code>Spock本身需要Groovy語言支持,所以也需要一個(gè)Groovy-all的依賴,請(qǐng)注意注自帶的注釋:

? ? ? <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>

另外,提供的配置文件中多了幾項(xiàng)特殊場(chǎng)景下使用的依賴,提供參考:

 ? <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)資源

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

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

三、Mock被測(cè)對(duì)象

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

用一個(gè)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單測(cè)代碼如下:

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屬性對(duì)象,無構(gòu)造方法

源代碼如下:

public class ApiImpl implements IApi {

? ? @Autowired
? ? private ApiRMapper mapper;
}

Spock單測(cè)部分代碼如下:

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用法

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

PS:如果對(duì)象屬性中有未被@Autowired注釋的屬性,不能用@AllArgsConstructor的lombok注解,服務(wù)啟動(dòng)會(huì)報(bào)錯(cuò)。

源代碼如下:

@Component
@Slf4j
public class TaskScheduled {

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

}

4.共享對(duì)象以及初始化

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

Spock框架Demo:

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

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

四、定義對(duì)象行為

1.Spock定義Mock對(duì)象行為

基礎(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方法的時(shí)候?qū)?shù)進(jìn)行了斷言和處理,這也是Spock框架的一個(gè)特性,其他均為Groovy語法特性。

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

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

2.Mockito模擬對(duì)象行為

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

定時(shí)對(duì)象行為:

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

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

其他常用定義行為:

? ? ? ? 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,什么都不做

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

通常我們需要構(gòu)建返回對(duì)象,如果對(duì)象需要賦值的屬性過多,可以使用初始化賦值的方法,下面是Mock一個(gè)返回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對(duì)象的方法經(jīng)驗(yàn)總結(jié)的文章就介紹到這了,更多相關(guān)Spock框架Mock對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java中覆蓋finalize()方法實(shí)例代碼

    Java中覆蓋finalize()方法實(shí)例代碼

    這篇文章主要介紹了Java中覆蓋finalize()方法實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • RocketMQ?Broker消息如何刷盤源碼解析

    RocketMQ?Broker消息如何刷盤源碼解析

    這篇文章主要為大家介紹了RocketMQ?Broker消息如何刷盤源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 一篇文章帶你深入了解Java基礎(chǔ)(4)

    一篇文章帶你深入了解Java基礎(chǔ)(4)

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • 淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題

    淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題

    本篇文章主要介紹了淺談利用Spring的AbstractRoutingDataSource解決多數(shù)據(jù)源的問題,具有一定的參考價(jià)值,有需要的可以了解一下
    2017-08-08
  • Java實(shí)現(xiàn)SHA-256加密算法的完全解析

    Java實(shí)現(xiàn)SHA-256加密算法的完全解析

    SHA-256是一種散列(哈希)算法,用于將任意長(zhǎng)度的數(shù)據(jù)映射為固定長(zhǎng)度的散列值,以保證數(shù)據(jù)完整性。本文將為大家介紹一下SHA-256加密算法的原理與實(shí)現(xiàn),希望對(duì)大家有所幫助
    2023-02-02
  • JDK、J2EE、J2SE、J2ME四個(gè)易混淆概念區(qū)分

    JDK、J2EE、J2SE、J2ME四個(gè)易混淆概念區(qū)分

    這篇文章將向你詳細(xì)介紹JDK、J2EE、J2SE、J2ME的概念以及他們的關(guān)系區(qū)別。
    2015-09-09
  • Java源碼重讀之ConcurrentHashMap詳解

    Java源碼重讀之ConcurrentHashMap詳解

    ConcurrentHashMap(CHM)是日常開發(fā)中使用頻率非常高的一種數(shù)據(jù)結(jié)構(gòu)。本文將從源碼角度帶大家深入了解一下ConcurrentHashMap的使用,需要的可以收藏一下
    2023-05-05
  • Spring?+?ECharts實(shí)現(xiàn)數(shù)據(jù)可視化的案例詳解

    Spring?+?ECharts實(shí)現(xiàn)數(shù)據(jù)可視化的案例詳解

    Apache?ECharts是一個(gè)基于?JavaScript?的開源可視化圖表庫,在網(wǎng)頁上實(shí)現(xiàn)數(shù)據(jù)的可視化,非常好用,本文將通過一個(gè)簡(jiǎn)單的demo來給大家介紹一下Spring?+?ECharts如何數(shù)據(jù)可視化,需要的朋友可以參考下
    2023-07-07
  • Java創(chuàng)建線程池的方式實(shí)現(xiàn)

    Java創(chuàng)建線程池的方式實(shí)現(xiàn)

    本文主要介紹了創(chuàng)建線程池的方式,包括三種方式,第一種是使用Executors框架,第二種是使用ThreadPoolExecutor,第三種是使用ForkJoinPool,感興趣的可以了解一下
    2024-12-12

最新評(píng)論

玉龙| 海门市| 乐亭县| 濮阳市| 五家渠市| 余干县| 泊头市| 宁海县| 湾仔区| 九龙城区| 富阳市| 衡山县| 临泽县| 云和县| 南昌县| 江陵县| 合川市| 柳河县| 清徐县| 贺兰县| 娄底市| 兴隆县| 高雄县| 万宁市| 积石山| 那坡县| 文水县| 石棉县| 祥云县| 肇东市| 乳源| 临桂县| 城市| 南漳县| 五指山市| 景洪市| 沂源县| 旺苍县| 馆陶县| 稷山县| 安图县|