You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复java.lang.IllegalStateException: Failed to unwrap proxied object错误

问题分析与解决方案

错误根源

你遇到的java.lang.IllegalStateException: Failed to unwrap proxied object错误,核心原因是:
通过@Autowired注入的FirebaseService是Spring生成的代理对象(可能是CGLIB或JDK动态代理),而Mockito的spy()方法无法直接处理这种代理实例,导致无法正确剥离代理获取真实对象,进而引发Stub方法失败。

解决方案

方案1:使用Spring Boot Test的@SpyBean(推荐)

Spring Boot Test提供的@SpyBean注解可以直接创建Spring管理Bean的Spy,自动处理代理问题,无需手动调用Mockito的spy()。

修改测试代码:

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class FirebaseServiceTest {

    // 用@SpyBean替代@Autowired+spy()
    @SpyBean
    private FirebaseService firebaseService;

    @Test
    public void whenGetAppIsEmpty_thenReturnFirebaseAppInstanceFromInitializeApp() throws IOException {
        // 直接Stub spyBean的方法
        doReturn(FileInputStream.nullInputStream())
            .when(firebaseService)
            .getServiceAccountFileInputStream();
        
        // 执行测试逻辑
        FirebaseApp app = firebaseService.initializeApp();
        // 断言逻辑...
    }
}

方案2:手动获取代理后的真实对象再Spy

如果坚持使用Mockito的spy(),需要先通过AopTestUtils.getTargetObject()获取Spring代理背后的真实对象,再创建Spy:

@ExtendWith(SpringExtension.class)
@SpringBootTest
public class FirebaseServiceTest {

    @Autowired
    private FirebaseService firebaseService;

    @Test
    public void whenGetAppIsEmpty_thenReturnFirebaseAppInstanceFromInitializeApp() throws IOException {
        // 获取代理后的真实对象
        FirebaseService realService = AopTestUtils.getTargetObject(firebaseService);
        // 创建真实对象的Spy
        FirebaseService firebaseServiceSpy = spy(realService);

        doReturn(FileInputStream.nullInputStream())
            .when(firebaseServiceSpy)
            .getServiceAccountFileInputStream();
        
        // 执行测试逻辑
        FirebaseApp app = firebaseServiceSpy.initializeApp();
        // 断言逻辑...
    }
}

注意:需要确保spring-test依赖已引入,AopTestUtils属于该依赖。

方案3:脱离Spring容器手动实例化(适合简单测试)

如果你的测试不需要Spring上下文的其他依赖,可以直接手动实例化FirebaseService,避免代理问题:

// 不需要@SpringBootTest等Spring注解
public class FirebaseServiceTest {

    @Test
    public void whenGetAppIsEmpty_thenReturnFirebaseAppInstanceFromInitializeApp() throws IOException {
        // 手动创建真实实例
        FirebaseService firebaseService = new FirebaseService(...); // 传入构造参数
        // 创建Spy
        FirebaseService firebaseServiceSpy = spy(firebaseService);

        doReturn(FileInputStream.nullInputStream())
            .when(firebaseServiceSpy)
            .getServiceAccountFileInputStream();
        
        // 执行测试逻辑
        FirebaseApp app = firebaseServiceSpy.initializeApp();
        // 断言逻辑...
    }
}

额外注意点

  • 检查getServiceAccountFileInputStream()方法是否为final:如果是final方法,Mockito无法Stub(对应错误提示的第2点),需要将该方法改为非final。
  • 你使用的doReturn(...).when(spy).method()是Spy对象Stub的正确语法(避免调用真实方法),这点本身没有问题,问题出在代理对象的处理上。

内容的提问来源于stack exchange,提问作者Israel Oluwole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:33:32