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

SpringBoot單元測試中@SpyBean使用小結(jié)

 更新時間:2025年08月25日 10:08:08   作者:zru_9602  
本文主要介紹了SpringBoot單元測試中@SpyBean使用小結(jié),@SpyBean用于部分模擬SpringBean,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 什么是@SpyBean?

@SpyBean 是 Spring Boot Test 提供的一個注解,用于在單元測試中**部分模擬(Partial Mock)**一個 Spring Bean。它類似于 Mockito 的 @Spy,但專門用于 Spring 容器中的 Bean。

  • @MockBean:完全模擬一個 Bean,所有方法都需要手動定義行為。
  • @SpyBean:基于真實(shí) Bean,只重寫(Mock)部分方法,其余方法仍然調(diào)用真實(shí)邏輯。

2. 何時使用@SpyBean?

? 適用場景

  • 你只想修改某個 Bean 的某個方法,但其他方法仍然走真實(shí)邏輯。
  • 你希望測試依賴某個 Bean 的真實(shí)邏輯,但需要控制其中某個方法的返回值。

? 不適用場景

  • 需要完全模擬整個 Bean(用 @MockBean)。
  • Bean 的方法是 finalstatic(Mockito 無法 Spy final 方法)。

3. 基本用法

示例場景

假設(shè)有一個 UserService 依賴 UserRepository,我們想測試 UserService,但只重寫 UserRepositoryfindById() 方法,其他方法(如 save())仍然走真實(shí)邏輯。

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public String getUserName(Long id) {
        User user = userRepository.findById(id).orElseThrow();
        return user.getName();
    }
}

測試代碼

@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @SpyBean  // 對 UserRepository 進(jìn)行 Spy,未 Mock 的方法仍然走真實(shí)邏輯
    private UserRepository userRepository;

    @Test
    public void testGetUserName() {
        // 準(zhǔn)備測試數(shù)據(jù)
        User mockUser = new User(1L, "Alice");
        userRepository.save(mockUser);  // 真實(shí)調(diào)用 save()

        // 只 Mock findById(),讓它返回自定義數(shù)據(jù)
        doReturn(Optional.of(new User(1L, "Mocked Alice")))
            .when(userRepository).findById(1L);

        // 調(diào)用測試方法
        String userName = userService.getUserName(1L);

        // 驗(yàn)證
        assertEquals("Mocked Alice", userName);

        // 其他方法仍然走真實(shí)邏輯
        User savedUser = userRepository.findById(2L).orElse(null);
        assertNull(savedUser);  // 因?yàn)闆]有存 ID=2 的用戶
    }
}

4.@SpyBean的常用 Mock 方式

(1)doReturn().when(spy).method()

// 讓方法返回固定值
doReturn("Mocked Result").when(mySpyBean).someMethod();

// 帶參數(shù)匹配
doReturn("Hello").when(mySpyBean).greet(anyString());

(2)doAnswer()(自定義邏輯)

doAnswer(invocation -> {
    String arg = invocation.getArgument(0);
    return "Processed: " + arg;
}).when(mySpyBean).process(anyString());

(3)doThrow()(模擬異常)

doThrow(new RuntimeException("DB Error"))
    .when(mySpyBean).save(any());

(4)doCallRealMethod()(顯式調(diào)用真實(shí)方法)

// 默認(rèn)會走真實(shí)方法,但也可以顯式聲明
doCallRealMethod().when(mySpyBean).someMethod();

5.@SpyBeanvs@MockBean

特性@SpyBean@MockBean
默認(rèn)行為未 Mock 的方法調(diào)用真實(shí)邏輯未 Mock 的方法返回默認(rèn)值(null/0/false)
適用場景只修改部分方法,其他方法仍需真實(shí)邏輯完全模擬 Bean,不依賴真實(shí)實(shí)現(xiàn)
性能稍慢(需代理真實(shí)對象)更快(純 Mock 對象)

6. 常見問題

Q1:@SpyBean能用于final方法嗎?

? 不能! Mockito 無法 Spy final 方法。如果遇到 final 方法,考慮:

  • 改用 @MockBean 完全模擬。
  • 重構(gòu)代碼,避免 final 方法。

Q2:@SpyBean和@Spy的區(qū)別?

  • @Spy 是 Mockito 提供的,用于普通對象。
  • @SpyBean 是 Spring Boot 提供的,用于 Spring Bean。

Q3: 如何驗(yàn)證方法調(diào)用次數(shù)?

// 驗(yàn)證 someMethod 被調(diào)用 1 次
verify(mySpyBean, times(1)).someMethod();

7. 總結(jié)

  • @SpyBean 適合部分 Mock,只修改某些方法,其余方法仍然走真實(shí)邏輯。
  • 常用方式
    • doReturn().when(spy).method():返回固定值。
    • doAnswer():自定義邏輯。
    • doThrow():模擬異常。
  • 不要用于 final 方法。

到此這篇關(guān)于SpringBoot單元測試中@SpyBean使用小結(jié)的文章就介紹到這了,更多相關(guān)SpringBoot @SpyBean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 調(diào)用wsdl協(xié)議接口簡單實(shí)用方法最新推薦

    java 調(diào)用wsdl協(xié)議接口簡單實(shí)用方法最新推薦

    文章介紹了如何使用POM導(dǎo)入依賴,并編寫一個測試類來調(diào)用不同的Web服務(wù)接口,通過訪問接口地址,我們可以獲取請求和返回的body,并進(jìn)一步解析返回的JSON結(jié)果,感興趣的朋友一起看看吧
    2025-03-03
  • 使用Java解析JSON數(shù)據(jù)并提取特定字段的實(shí)現(xiàn)步驟(以提取mailNo為例)

    使用Java解析JSON數(shù)據(jù)并提取特定字段的實(shí)現(xiàn)步驟(以提取mailNo為例)

    在現(xiàn)代軟件開發(fā)中,處理JSON數(shù)據(jù)是一項(xiàng)非常常見的任務(wù),無論是從API接口獲取數(shù)據(jù),還是將數(shù)據(jù)存儲為JSON格式,解析和提取JSON中的特定字段都是開發(fā)人員需要掌握的基本技能,本文將以一個實(shí)際案例為例,詳細(xì)介紹如何使用Java解析JSON數(shù)據(jù)并提取其中的mailNo字段
    2025-01-01
  • java實(shí)現(xiàn)excel導(dǎo)出合并單元格的步驟詳解

    java實(shí)現(xiàn)excel導(dǎo)出合并單元格的步驟詳解

    這篇文章主要介紹了java實(shí)現(xiàn)excel導(dǎo)出合并單元格,通過使用Apache POI庫,我們可以方便地創(chuàng)建Excel文件、填充數(shù)據(jù)、合并單元格和導(dǎo)出Excel文件,需要的朋友可以參考下
    2023-04-04
  • java學(xué)習(xí)筆記之eclipse+tomcat 配置

    java學(xué)習(xí)筆記之eclipse+tomcat 配置

    俗話說:工欲善其事必先利其器,既然要學(xué)習(xí)java,首先把java的開發(fā)環(huán)境搗鼓一下吧,這里我們來談?wù)別clipse+tomcat的配置方法。
    2014-11-11
  • 基于params、@PathVariabl和@RequestParam的用法與區(qū)別說明

    基于params、@PathVariabl和@RequestParam的用法與區(qū)別說明

    這篇文章主要介紹了方法參數(shù)相關(guān)屬性params、@PathVariabl和@RequestParam用法與區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring的事務(wù)機(jī)制實(shí)例代碼

    Spring的事務(wù)機(jī)制實(shí)例代碼

    這篇文章主要介紹了Spring的事務(wù)機(jī)制實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • logback之自定義指定日志文件存儲目錄方式

    logback之自定義指定日志文件存儲目錄方式

    這篇文章主要介紹了logback之自定義指定日志文件存儲目錄方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java編程實(shí)現(xiàn)月食簡單代碼分享

    Java編程實(shí)現(xiàn)月食簡單代碼分享

    這篇文章主要介紹了Java編程實(shí)現(xiàn)月食簡單代碼分享,程序很簡單,喜歡的朋友可以拿過去玩玩。
    2017-11-11
  • Java實(shí)現(xiàn)將二叉樹展開為鏈表的兩種方法

    Java實(shí)現(xiàn)將二叉樹展開為鏈表的兩種方法

    文章介紹了兩種方法將二叉樹按前序遍歷順序展開為單鏈表,方法一為迭代法,方法二為前序遍歷+列表重建,兩者各有優(yōu)缺點(diǎn),選擇時需根據(jù)實(shí)際需求和場景考慮,下面小編給大家詳細(xì)說說
    2025-05-05
  • 分析Java非阻塞算法Lock-Free的實(shí)現(xiàn)

    分析Java非阻塞算法Lock-Free的實(shí)現(xiàn)

    非阻塞算法一般會使用CAS來協(xié)調(diào)線程的操作。雖然非阻塞算法有諸多優(yōu)點(diǎn),但是在實(shí)現(xiàn)上要比基于鎖的算法更加繁瑣和負(fù)責(zé)。本文將會介紹兩個是用非阻塞算法實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)。
    2021-06-06

最新評論