如何用JUnit4测试Kotlin字符串转货币函数的异常并通过测试
修复Kotlin货币格式化函数的JUnit4测试用例
原扩展函数
fun String.toCurrency(): String{ return try { DecimalFormat("###,###").format(this.replace(",","").toInt()) } catch (e: NumberFormatException) { this } }
原测试失败原因
- 错误的异常预期:原测试标注了
@Test(expected = NumberFormatException::class),但扩展函数内部已经捕获了NumberFormatException并返回原字符串,永远不会向外抛出该异常,导致测试直接失败。 - 断言类型不匹配:
assertEquals(NumberFormatException::class, e)中,NumberFormatException::class是KClass类型,而e是异常实例,两者类型不匹配,断言必然失败。 - API使用错误:Kotlin中没有
forEachWithIndex,正确的API是forEachIndexed。
修改后的测试用例
将测试拆分为两个独立的测试方法,分别验证正常格式化场景和异常输入场景:
import org.junit.Test import org.junit.Assert.assertEquals class StringExtensionTest { @Test fun toCurrency_formatsValidStringsCorrectly() { val inputList = listOf("0", "1", "10", "100", "1000", "10000", "100000", "1000000", "100000000") val expectedList = listOf("0", "1", "10", "100", "1,000", "10,000", "100,000", "1,000,000", "100,000,000") inputList.forEachIndexed { index, input -> assertEquals(expectedList[index], input.toCurrency()) } } @Test fun toCurrency_returnsOriginalStringForInvalidInputs() { val invalidInputs = listOf("!", "@", "abc", "12a34") invalidInputs.forEach { input -> assertEquals(input, input.toCurrency()) } } }
关键修改说明
- 拆分测试:将正常格式化和异常输入的验证分开,每个测试只关注单一场景,提升测试可读性和维护性。
- 移除错误的异常预期:由于原函数内部捕获异常并返回原字符串,无需测试函数抛出异常,转而验证异常输入时的返回值是否符合预期。
- 修正API调用:将
forEachWithIndex替换为Kotlin标准的forEachIndexed。 - 正确断言:对于异常输入,直接断言函数返回原字符串,符合原扩展函数的逻辑。
内容的提问来源于stack exchange,提问作者c-an
相关产品推荐
相关产品推荐

