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

如何正确使用Mockito模拟带回调的方法?

如何Mock带回调参数的方法直接触发onSuccess/onError?

现有方法实现

我有如下方法:

override fun functionToBeMocked(
    param: Param,
    onSuccess: (param: Param) -> Unit,
    onError: (param: Param, errorMessage: String) -> Unit
) {
    val response = factory.request(param)
        .exchange()
        .block()

    if (response?.statusCode()?.is2xxSuccessful == true) {
        onSuccess(param)
    } else if (response?.statusCode()?.isError == true) {
        val status = response.rawStatusCode()
        val body = response.bodyToMono(String::class.java).block()
        val errorMessage = "$status : $body"
        onError(param, errorMessage)
    } else {
        return
    }
}

测试需求

我想要测试调用该方法的服务,该方法传入了指定的onSuccess和onError函数。需要Mock functionToBeMocked(),使其直接执行onSuccess(param)或onError(param)。

当前测试代码:

@Test
fun test() {

    val failure = ParamDoc(param.id, param)
    whenever(repo.findAll()).thenReturn(listOf(failure))
    
    // 此方法调用应根据测试用例执行onSuccess()或onError
    // whenever(mockedService.functionToBeMocked).thenAnswer.. (?)

    underTest.functionToBeTested()

    // verify(..)
}

补充:factory中的request函数:

fun request(param: Param): WebClient.RequestHeadersSpec<*> {
    val client = WebClient
            .builder()
            .defaultHeader("API-KEY", config.apiKey)
            .baseUrl(config.baseUrl)
            .build()

    return client
            .post()
            .uri("/service/test")
            .contentType(MediaType.APPLICATION_JSON)
            .bodyValue(Dto.fromParam(param))
}

解决方案

使用Mockito的thenAnswer可以获取方法调用时传入的所有参数,然后直接触发对应的回调函数:

1. Mock触发onSuccess回调

whenever(mockedService.functionToBeMocked(any(), any(), any())).thenAnswer { invocation ->
    // 获取传入的param参数
    val param = invocation.getArgument<Param>(0)
    // 获取onSuccess回调函数
    val onSuccess = invocation.getArgument<(Param) -> Unit>(1)
    // 执行回调
    onSuccess(param)
    // 方法返回值(原方法为Unit,直接返回Unit即可)
    Unit
}

2. Mock触发onError回调

whenever(mockedService.functionToBeMocked(any(), any(), any())).thenAnswer { invocation ->
    val param = invocation.getArgument<Param>(0)
    val onError = invocation.getArgument<(Param, String) -> Unit>(2)
    // 传入自定义错误信息
    onError(param, "自定义错误内容")
    Unit
}

注意事项

  • 确保mockedService是通过@Mock注解或者mock(Service::class.java)创建的Mock实例
  • 如果需要针对特定Param进行Mock,可以把any()替换为eq(targetParam)来精准匹配参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:30:49