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

单元测试引用CookieManager的logout函数遇NoSuchMethodError的原因与解决

问题:CookieManager.removeAllCookies测试报错NoSuchMethodError

核心业务代码

应用的logout函数执行时会调用CookieManager.getInstance().removeAllCookies(null),核心代码如下:

fun logout(...) {                                                                           
    showLoader(true)                                                           
                                                                                                                                        
    msgRepo.unregisterSendBirdHandlersAndPushToken(                            
        onSuccess = {                                                          
            clearUserData(...)
            // ...                                        
            onLogout()                                                         
        },                                                                     
        onFailure = {                                                           
            clearUserData(...)
            // ...                                        
            onLogout()                                                         
        }                                                                      
    )                                                                          
}                                                                                                                                        
                                                                              
/**                                                                            
 * Helper to clear user data before logging user out                           
 */                                                                            
private fun clearUserData(...) {                                                                           
    // ...                                             
    CookieManager.getInstance().removeAllCookies(null)
}

测试用例示例

编写的调用logout的测试用例示例:

@Test                                                              
fun `verify logout with success`() {                               
    // .. Other code                                                             
    HardLogoutHelper.logout(...)                                                              
    // ...                            
}

报错信息

测试时触发如下错误:

'void android.webkit.CookieManager.removeAllCookies(android.webkit.ValueCallback)'
java.lang.NoSuchMethodError: 'void android.webkit.CookieManager.removeAllCookies(android.webkit.ValueCallback)'
at com.example.helpers.HardLogoutHelper.clearUserData(HardLogoutHelper.kt:86)

已尝试的方案

  • 使用@RunWith(RoboelectricTestRunner::class)运行测试
  • 为CookieManager创建自定义Roboelectric Shadow,但问题仍未解决

错误原因

  1. API版本不匹配:CookieManager.removeAllCookies(ValueCallback) 是Android API 21(Android 5.0)才新增的方法,若你的测试环境(Roboelectric指定的SDK版本)低于API 21,就会出现找不到方法的错误。
  2. Shadow类未正确覆盖方法:Roboelectric自带的ShadowCookieManager可能未对该方法做适配,或者你自定义的Shadow类没有正确实现该方法的签名(比如参数类型不对、未指定minSdk)。

修复方案

方案1:指定Roboelectric测试的SDK版本为API 21+

在测试类上添加@Config注解,强制测试环境使用包含目标方法的SDK版本:

@RunWith(RoboelectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.LOLLIPOP])
class HardLogoutHelperTest {
    // 测试用例
}

方案2:修改业务代码做版本兼容

如果应用需要兼容API 21以下的设备,在clearUserData中加入版本判断,调用对应版本的方法:

private fun clearUserData(...) {
    // ...
    val cookieManager = CookieManager.getInstance()
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        cookieManager.removeAllCookies(null)
    } else {
        @Suppress("DEPRECATION")
        cookieManager.removeAllCookie() // API 21以下的废弃方法,无回调参数
    }
}

方案3:正确实现自定义ShadowCookieManager

若坚持使用自定义Shadow,需确保Shadow类正确覆盖API 21+的方法,并指定minSdk:

@Implements(CookieManager.class)
public class ShadowCustomCookieManager extends ShadowCookieManager {
    @Implementation(minSdk = Build.VERSION_CODES.LOLLIPOP)
    public void removeAllCookies(ValueCallback<Boolean> callback) {
        // 自定义实现逻辑,比如直接回调成功
        if (callback != null) {
            callback.onReceiveValue(true);
        }
    }
}

然后在测试类的@Config中指定使用该Shadow:

@RunWith(RoboelectricTestRunner::class)
@Config(
    sdk = [Build.VERSION_CODES.LOLLIPOP],
    shadows = [ShadowCustomCookieManager::class]
)
class HardLogoutHelperTest {
    // 测试用例
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:45:29