Использование проверки для проверки строки в Kotlin не удается - PullRequest
0 голосов
/ 11 января 2020

У меня есть приложение, в котором пользователи должны вводить разные строки. В зависимости от характера строки в приложении, оно должно следовать некоторым правилам, например, если это имя, оно должно начинаться с буквы.

Я написал правило, чтобы убедиться, что строка допустима в случае строки, которая должна начинаться с буквы, я написал следующее правило:

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

Расширение функции проверяет все правила, применимые к указанной строке c:

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 не начинается с буквы, я ожидаю, что возникает исключение IllegalStateException, когда создается экземпляр Name с этой строкой, поэтому приведенный выше тест должен пройти успешно.

Но проверка не проходит со следующим сообщением:

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

Кто-нибудь видит, где я делаю ошибку?

Ответы [ 2 ]

1 голос
/ 11 января 2020

Чтобы запустить оператор вызова, вам нужно было позвонить

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

Затем будет вызван вызов с исключением

Возможно, вам следует проверить первую букву в секции init {}?

class Name(private val string:String) {

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

Вы также можете использовать регулярные выражения, чтобы проверить, начинается ли строка с буквы

0 голосов
/ 11 января 2020

Я нашел решение:)

Как указано здесь : Оператор invoke () позволяет вызывать экземпляры ваших классов как функции. (я мог не найти описание invoke в официальной документации, если кто-нибудь знает, где оно ...)

Принимая вышеприведенное определение @ Илья Кузьмин, я могу использовать блок init.

Но если я объявлю конструктор моего класса Name как private, у меня будет такое поведение, которое я хочу. invoke затем используется, когда я создаю экземпляр Name объекта:

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

После исправления все мои тесты завершаются успешно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...