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

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

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

1. 什么是@SpyBean?

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

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

2. 何時(shí)使用@SpyBean?

? 適用場景

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

? 不適用場景

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

3. 基本用法

示例場景

假設(shè)有一個(gè) 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)文章

最新評論

景德镇市| 乾安县| 大庆市| 武安市| 太白县| 土默特右旗| 武清区| 将乐县| 商城县| 仲巴县| 宁远县| 韶关市| 萨迦县| 新郑市| 犍为县| 磐安县| 新泰市| 福安市| 莎车县| 德安县| 房产| 昭苏县| 北辰区| 景德镇市| 崇明县| 铜梁县| 巴马| 清镇市| 北票市| 寻乌县| 黔西县| 且末县| 丰台区| 启东市| 黎川县| 南华县| 博野县| 灌南县| 杭州市| 南雄市| 宁津县|