【问题标题】:Using check to validate a string in Kotlin fails在 Kotlin 中使用 check 验证字符串失败
【发布时间】:2020-01-11 19:23:58
【问题描述】:

我有一个应用程序,用户必须输入不同的字符串。根据应用程序中字符串的性质,它必须遵循一些规则,例如,如果它是名称,则必须以字母开头。

我写了一个规则来确保一个字符串是有效的,对于一个必须以字母开头的字符串我写了以下规则:

fun String.isFirstCharALetter(): Boolean = this[0].isLetter()

函数扩展检查适用于特定字符串的所有规则:

fun String.validateName(): String {
    check(this.isFirstCharALetter()) { "The first character of a name can only be a letter" }
    //... other checks
    return this
}

我使用这个函数扩展来实例化 Name 只有当字符串有效时(至少这是我的意图):

data class Name(val value: String) {
    companion object {
        operator fun invoke(strg: String) {
            Name(value= strg.validate())
        }
    }
}

我写了以下单元测试:

@Test
fun test_assert_name() {
    assertFailsWith<IllegalStateException> { Name("8foo") }
}

由于 8foo 不以字母开头,我希望在使用此字符串实例化 Name 时会引发 IllegalStateException 异常,因此上述测试必须成功。

但测试失败并显示以下消息:

java.lang.AssertionError: Expected an exception of class java.lang.IllegalStateException to be thrown, but was completed successfully.

有人看到我在哪里出错了吗?

【问题讨论】:

  • 当您执行Name("8foo") 时,您不会调用伴随对象的方法。您正在调用构造函数(类似于 Java 中的 new Name("8foo")
  • 你是对的@Pelocho,构造函数必须是私有的,看我的回答
  • 这种将收入函数放在伴生对象上的模式从何而来?这两天我看过两次。似乎它会使代码变得脆弱,就像这里所做的那样。
  • *调用函数
  • 我发现了几个在伴随对象中使用invoke 的示例(例如:kotlinlang)。为什么说它会使代码变得脆弱?

标签: android unit-testing testing exception kotlin


【解决方案1】:

要运行调用运算符,您需要调用

val name = Name("8foo")
name("8foo")

然后invoke会被异常调用

也许您应该检查 init{} 部分的第一个字母?

class Name(private val string:String) {

    init{
        check(false){"Error"}
    }

您也可以使用正则表达式检查字符串是否以字母开头

【讨论】:

  • 小心正则表达式!对于像这样的简单任务,使用正则表达式完全是矫枉过正。看看blog.codinghorror.com/…
【解决方案2】:

我找到了解决方案:)

here 所述:invoke() 运算符允许将类的实例作为函数调用。(如果有人的话,我在官方文档中找不到invoke 的描述知道它在哪里...)

采用上面@Илья Кузьмин 的定义是正确的,我可以使用init 块。

但是如果我将我的类Name 的构造函数声明为private,我就有了我想要的行为。然后在我实例化Name 对象时使用invoke

data class Name private constructor(val value: String) {
    companion object {
        operator fun invoke(value: String) = Name(value= value.validate())
    }
}

进行此修复后,我的所有测试都成功了。

【讨论】:

    猜你喜欢
    • 2019-03-31
    • 2021-06-19
    • 2017-04-30
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多