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

Kotlin JUnit 4测试中无法捕获异常的问题求助

单元测试校验JSON合法性时异常未捕获的问题解决

我懂你现在的困扰——本来想靠创建JSONObject/JSONArray加捕获异常的方式,来校验字符串是不是合法JSON,结果运行测试时异常根本没被触发,完全不符合预期。咱们来一步步拆解问题,找到解决办法。

先说说你的代码里可能藏的坑

你的测试代码是这样的:

@Test fun checkFunctionWithStringToJSONTest() { 
    val invalidJSON = "INVALIDJSON--" 
    try { 
        JSONObject(invalidJSON) 
    } catch (ex: Exception) { 
        try { 
            JSONArray(invalidJSON) 
        } catch (ex1: Exception) { 
            assert(false) 
        } 
    } 
    assert(true) 
}

这里可能出问题的地方有这几个:

1. 用错了JSON库

这是最常见的原因!如果你用的是Gson的JsonObject而不是Android原生的org.json.JSONObject,那直接传字符串给构造器根本不会触发解析——Gson的JsonObject构造器是空的,根本不处理字符串,自然不会抛异常。这种情况下,你得用Gson的解析方法才会触发错误。

2. 异常捕获和断言逻辑不够严谨

就算用的是Android原生库,泛泛地捕获Exception虽然能覆盖JSONException,但你的断言逻辑有点绕:只有当两种解析都失败时才会assert(false),否则直接走到assert(true)。如果你的测试用例是无效JSON,那预期应该是测试失败,但如果异常没被捕获,说明库的解析逻辑出了问题——但"INVALIDJSON--"这种字符串绝对不可能被合法解析,所以还是大概率库用错了。

给你两种场景下的修正方案

场景1:用Android原生org.json库

这种情况下,咱们明确捕获JSONException,同时把逻辑理得更清晰,测试失败时还能给出明确提示:

import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

// 测试无效JSON的情况
@Test fun invalidJSONShouldBeRejected() {
    val invalidJSON = "INVALIDJSON--"
    var isJSONValid = false

    try {
        // 先尝试解析为JSON对象
        JSONObject(invalidJSON)
        isJSONValid = true
    } catch (ex: JSONException) {
        try {
            // 对象解析失败,尝试解析为JSON数组
            JSONArray(invalidJSON)
            isJSONValid = true
        } catch (ex1: JSONException) {
            // 两种都失败,说明不是合法JSON
            isJSONValid = false
        }
    }

    // 无效JSON预期是false,断言失败时会显示提示语
    assertFalse(isJSONValid, "该字符串不是合法的JSON格式")
}

// 测试合法JSON的情况,确保逻辑正确
@Test fun validJSONShouldBeAccepted() {
    val validJSONObject = "{\"name\":\"test\"}"
    val validJSONArray = "[1,2,3]"

    // 校验合法JSON对象
    var isJSONValid = false
    try {
        JSONObject(validJSONObject)
        isJSONValid = true
    } catch (ex: JSONException) {
        try {
            JSONArray(validJSONObject)
            isJSONValid = true
        } catch (ex1: JSONException) {
            isJSONValid = false
        }
    }
    assertTrue(isJSONValid, "合法JSON对象应该被正确识别")

    // 校验合法JSON数组
    isJSONValid = false
    try {
        JSONObject(validJSONArray)
        isJSONValid = true
    } catch (ex: JSONException) {
        try {
            JSONArray(validJSONArray)
            isJSONValid = true
        } catch (ex1: JSONException) {
            isJSONValid = false
        }
    }
    assertTrue(isJSONValid, "合法JSON数组应该被正确识别")
}

场景2:用Gson库

如果是用Gson,就得用它的fromJson方法来触发解析,而不是直接构造JsonObject:

import com.google.gson.Gson
import com.google.gson.JsonSyntaxException
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

@Test fun checkJSONValidityWithGson() {
    val invalidJSON = "INVALIDJSON--"
    val validJSON = "{\"key\":\"value\"}"
    val gson = Gson()

    // 测试无效JSON
    var isJSONValid = false
    try {
        // 用Any类型可以同时兼容对象和数组
        gson.fromJson(invalidJSON, Any::class.java)
        isJSONValid = true
    } catch (ex: JsonSyntaxException) {
        isJSONValid = false
    }
    assertFalse(isJSONValid, "无效字符串应该被识别为非JSON")

    // 测试有效JSON
    isJSONValid = false
    try {
        gson.fromJson(validJSON, Any::class.java)
        isJSONValid = true
    } catch (ex: JsonSyntaxException) {
        isJSONValid = false
    }
    assertTrue(isJSONValid, "合法JSON应该被正确识别")
}

额外的小建议

可以把校验JSON合法性的逻辑抽成一个单独的工具函数,比如:

fun isJSONValid(str: String): Boolean {
    return try {
        JSONObject(str)
        true
    } catch (ex: JSONException) {
        try {
            JSONArray(str)
            true
        } catch (ex1: JSONException) {
            false
        }
    }
}

这样测试代码会更简洁,而且这个函数还能在其他业务逻辑里复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:43:03