Kotlin中的object
关键字以非常方便的方式创建单例。 例如,它可以用作操作状态。 Spock框架是Java生态系统中最具表达力和可读性的测试框架之一。 让我们看看如何在Spock测试中使用Kotlin object
。
我们要测试什么?
我们在Validator
接口中有一个方法validate
,它返回验证状态: Ok
或Error
。
sealed class ValidationStatus
object Ok : ValidationStatus()
object Error : ValidationStatus()
interface Validator<T> {
fun validate(value: T): ValidationStatus
}
我们还提供此接口的简单实现:
class AdultValidator : Validator<Int> {
override fun validate(value: Int) = if (value >= 18) Ok else Error
}
如何用Spock进行测试?
第一–愚蠢的做法
首先,让我们为验证器编写一个参数化测试:
AdultValidator sut = new AdultValidator()
def 'should validate age #age'() {
expect:
sut.validate(age) == result
where:
age | result
0 | Error
17 | Error
18 | Ok
19 | Ok
}
我们希望它能够通过,但是会失败... Error
和Ok
是上面代码中的类。
第二–天真的方法
我们需要实例,所以我们稍微修改一下测试:
def 'should validate age #age'() {
expect:
sut.validate(age) == result
where:
age | result
0 | new Error()
17 | new Error()
18 | new Ok()
19 | new Ok()
}
再一次,这个失败了。 为什么? 这是因为Error
和Ok
类没有重写的equals
方法。 但为什么? 我们希望Kotlin对象(使用object
关键字而非普通对象创建的对象)能够正确实现。 而且,它在Kotlin中可以正常工作:
fun isOk(status:ValidationStatus) = status == Ok
第三–正确的方法
让我们看一下类文件:
$ javap com/github/alien11689/testingkotlinwithspock/Ok.class
Compiled from "Validator.kt"
public final class com.github.alien11689.testingkotlinwithspock.Ok extends com.github.alien11689.testingkotlinwithspock.ValidationStatus {
public static final com.github.alien11689.testingkotlinwithspock.Ok INSTANCE;
static {};
}
如果我们想访问Kotlin在这种比较中使用的真实对象,那么我们应该访问称为INSTANCE
的类静态属性:
def 'should validate age #age'() {
expect:
sut.validate(age) == result
where:
age | result
0 | Error.INSTANCE
17 | Error.INSTANCE
18 | Ok.INSTANCE
19 | Ok.INSTANCE
}
现在测试通过了。
第四–替代方法
我们也可以在没有对象类的特定实例的情况下检查方法结果,而改用instanceof
或Class#isAssignableFrom
。
def 'should validate age #age'() {
when:
ValidationStatus result = sut.validate(age)
then:
result.class.isAssignableFrom(expected)
where:
age | expected
0 | Error
17 | Error
18 | Ok
19 | Ok
}
给我看代码
代码可以在这里找到 ;
翻译自: https://www.javacodegeeks.com/2018/03/testing-kotlin-with-spock-part-1-object.html