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

Android Studio测试字符串匹配异常求助:看似相同为何不匹配?

字符串看似相同但断言失败的原因:空格字符编码不同

你看到的两个字符串视觉上一致,但实际是两种完全不同的空格字符:

  • 预期字符串中的是普通空格(ASCII码32,字符 )
  • 实际返回字符串中的是非断行空格(NBSP)(Unicode编码U+00A0,视觉上和普通空格无区别,但编码值不同)

为什么会出现这个差异?

NumberFormat.getCurrencyInstance()的输出会遵循当前Locale的货币格式化规则,很多地区的格式规范中,货币符号与数字之间会使用非断行空格(避免符号和数字在换行时被拆分),而你手动编写的预期字符串用的是普通空格,导致字符串全等比较失败。

解决方法

方法1:用相同的格式化工具生成预期值

避免硬编码字符串,直接用NumberFormat生成预期结果,确保空格类型一致:

@Test
fun calculate_20_percent_tip_no_roundup() {
    val amount = 10.00
    val tipPercent = 20.00
    val expectedTip = NumberFormat.getCurrencyInstance().format(2.00)
    val actualTip = calculateTip(amount = amount, percent = tipPercent, false)
    assertEquals(expectedTip, actualTip)
}

方法2:明确指定Locale消除环境差异

不同测试环境的默认Locale可能不同,统一指定Locale可以确保格式化规则一致:

// 修改calculateTip方法
@VisibleForTesting
internal fun calculateTip(
    amount: Double, percent: Double = 15.0, roundUp: Boolean): String{
    var tip = percent / 100 * amount
    if (roundUp)
        tip = kotlin.math.ceil(tip)
    // 指定固定Locale,比如法国Locale
    return NumberFormat.getCurrencyInstance(Locale.FRANCE).format(tip)
}

// 测试代码同步指定Locale
@Test
fun calculate_20_percent_tip_no_roundup() {
    val amount = 10.00
    val tipPercent = 20.00
    val expectedTip = NumberFormat.getCurrencyInstance(Locale.FRANCE).format(2.00)
    val actualTip = calculateTip(amount = amount, percent = tipPercent, false)
    assertEquals(expectedTip, actualTip)
}

方法3:硬编码时使用非断行空格的Unicode转义

如果必须硬编码预期字符串,直接用Unicode转义字符\u00A0表示非断行空格:

@Test
fun calculate_20_percent_tip_no_roundup() {
    val amount = 10.00
    val tipPercent = 20.00
    val expectedTip = "2,00\u00A0$"
    val actualTip = calculateTip(amount = amount, percent = tipPercent, false)
    assertEquals(expectedTip, actualTip)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:26:12