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

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

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

1. 什么是@SpyBean?

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

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

2. 何時使用@SpyBean?

? 適用場景

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

? 不適用場景

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

3. 基本用法

示例場景

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

@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 進行 Spy,未 Mock 的方法仍然走真實邏輯
    private UserRepository userRepository;

    @Test
    public void testGetUserName() {
        // 準備測試數(shù)據(jù)
        User mockUser = new User(1L, "Alice");
        userRepository.save(mockUser);  // 真實調(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);

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

        // 其他方法仍然走真實邏輯
        User savedUser = userRepository.findById(2L).orElse(null);
        assertNull(savedUser);  // 因為沒有存 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)用真實方法)

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

5.@SpyBeanvs@MockBean

特性@SpyBean@MockBean
默認行為未 Mock 的方法調(diào)用真實邏輯未 Mock 的方法返回默認值(null/0/false)
適用場景只修改部分方法,其他方法仍需真實邏輯完全模擬 Bean,不依賴真實實現(xiàn)
性能稍慢(需代理真實對象)更快(純 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: 如何驗證方法調(diào)用次數(shù)?

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

7. 總結(jié)

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

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

相關(guān)文章

最新評論

建湖县| 常山县| 肇东市| 南通市| 乌什县| 菏泽市| 体育| 武陟县| 桓仁| 遂昌县| 广元市| 藁城市| 姚安县| 岗巴县| 左贡县| 满城县| 沙洋县| 长乐市| 龙井市| 洪雅县| 大姚县| 偏关县| 石狮市| 洞头县| 东平县| 东山县| 明水县| 北流市| 长岭县| 凤山市| 抚州市| 高邑县| 开化县| 大田县| 莱西市| 宕昌县| 临颍县| 定南县| 丰城市| 福安市| 南乐县|