结合 null 安全和 assertNotNull
Combine null safety and assertNotNull
在测试中我们通常有assertNotNull
,但它不会执行从可空类型到非可空类型的智能转换。我必须写这样的东西:
if (test == null) {
Assert.fail("")
return
}
仅通过 assertNotNull
调用执行智能转换是否是解决方法?你是怎么处理的?
遗憾的是,您调用的函数体(包括内联函数)不用于智能转换和可空性推断。
您的代码中没有太多可以改进的地方,我只建议一件事:您可以对这些断言语句使用 the Elvis operator with a Nothing
函数。控制流分析考虑了导致 Nothing
的分支并从中推断出可空性:
fun failOnNull(): Nothing = throw AssertionError("Value should not be null")
val test: Foo? = foo()
test ?: failOnNull()
// `test` is not-null after that
这也可以不用函数写成:test ?: throw AssertionError("...")
,因为 throw
表达式也有类型 Nothing
.
谈到断言失败的更一般情况,可以使用 fail(...): Nothing
函数,它也为控制流分析提供了额外的提示。 JUnit Assert.fail(...)
不是 Nothing
函数,但您可以在 kotlin-test-junit
模块中找到一个或自己编写一个。
test as? SomeType ?: fail("`test` should be an instance of SomeType")
// smart cast works here, `test` is `SomeType`
kotlin.test 库为此提供了一个简单的解决方案:
kotlin.test.assertNotNull()
因为这个函数实现了 Kotlin 合约,所以它支持智能转换:
contract { returns() implies (actual != null) }
示例:
fun Foo?.assertBar() {
assertNotNull(this)
assertEquals(this.bar, 0)
}
只需确保使用正确的 assertNotNull
导入 (import kotlin.test.assertNotNull
)!
如果您还没有使用 kotlin.test
库,请将其添加到您的项目中:
group: 'org.jetbrains.kotlin', name: 'kotlin-test', version: '1.3.11
非常感谢@Rolf 将我指向 assertNotNull method offered by the kotlin-test library in his answer 。
我只想补充并指出此方法具有非空 return 类型(即它 return 是作为非空对象传递给它的可空对象).因此,如果您在测试中强制展开属性,您可以摆脱这种做法并按如下方式改进您的测试:
val myProperty = assertNotNull(myObject?.myProperty)
assertEquals("Foo", myProperty.someOtherProperty)
在测试中我们通常有assertNotNull
,但它不会执行从可空类型到非可空类型的智能转换。我必须写这样的东西:
if (test == null) {
Assert.fail("")
return
}
仅通过 assertNotNull
调用执行智能转换是否是解决方法?你是怎么处理的?
遗憾的是,您调用的函数体(包括内联函数)不用于智能转换和可空性推断。
您的代码中没有太多可以改进的地方,我只建议一件事:您可以对这些断言语句使用 the Elvis operator with a Nothing
函数。控制流分析考虑了导致 Nothing
的分支并从中推断出可空性:
fun failOnNull(): Nothing = throw AssertionError("Value should not be null")
val test: Foo? = foo()
test ?: failOnNull()
// `test` is not-null after that
这也可以不用函数写成:test ?: throw AssertionError("...")
,因为 throw
表达式也有类型 Nothing
.
谈到断言失败的更一般情况,可以使用 fail(...): Nothing
函数,它也为控制流分析提供了额外的提示。 JUnit Assert.fail(...)
不是 Nothing
函数,但您可以在 kotlin-test-junit
模块中找到一个或自己编写一个。
test as? SomeType ?: fail("`test` should be an instance of SomeType")
// smart cast works here, `test` is `SomeType`
kotlin.test 库为此提供了一个简单的解决方案:
kotlin.test.assertNotNull()
因为这个函数实现了 Kotlin 合约,所以它支持智能转换:
contract { returns() implies (actual != null) }
示例:
fun Foo?.assertBar() {
assertNotNull(this)
assertEquals(this.bar, 0)
}
只需确保使用正确的 assertNotNull
导入 (import kotlin.test.assertNotNull
)!
如果您还没有使用 kotlin.test
库,请将其添加到您的项目中:
group: 'org.jetbrains.kotlin', name: 'kotlin-test', version: '1.3.11
非常感谢@Rolf 将我指向 assertNotNull method offered by the kotlin-test library in his answer
我只想补充并指出此方法具有非空 return 类型(即它 return 是作为非空对象传递给它的可空对象).因此,如果您在测试中强制展开属性,您可以摆脱这种做法并按如下方式改进您的测试:
val myProperty = assertNotNull(myObject?.myProperty)
assertEquals("Foo", myProperty.someOtherProperty)