【发布时间】:2021-08-03 12:00:45
【问题描述】:
我有 Kotlin 课程和 Groovy/Spock 测试。当我模拟一个 Kotlin 类并在模拟上设置一个属性值时,它无法传递给 Kotlin。
这是一个 Kotlin 实体类,以及一个使用它的类:
open class TestEntity(var prop: String) {
}
class AClassUnderTest {
fun useATestEntity(testEntity: TestEntity) {
System.out.println("Checking it isn't null within Kotlin code: " + (testEntity.prop))
System.out.println("Code which assumes it is not null: " + testEntity.prop.length)
}
}
这是一个模拟 TestEntity,模拟 getProp() 方法,然后调用 Kotlin 方法来使用它的测试:
class AClassUnderTestTest extends Specification {
def "UseATestEntity"() {
given:
def cut = new AClassUnderTest()
def testEntityMock = GroovyMock(TestEntity)
testEntityMock.getProp() >> "abc"
System.out.println("Checking it isn't null after mocking: " + (testEntityMock.prop))
when:
System.out.println("Checking it isn't null during when clause: " + (testEntityMock.prop))
cut.useATestEntity(testEntityMock)
then:
noExceptionThrown()
}
}
预期的行为是演示 println 的全部显示“abc”并且方法成功
观察到的行为是 Kotlin 中的 println 显示属性为 null,并且方法失败:
Checking it isn't null after mocking: abc
Checking it isn't null during when clause: abc
Checking it isn't null within Kotlin code: null
Expected no exception to be thrown, but got 'java.lang.NullPointerException'
我做错了什么?
如何模拟 Kotlin 类并在其上设置一个值,以便在 Kotlin 代码和 Groovy 代码中检索模拟值?
已经试过了:
- 使用 GroovyStub() 代替 GroovyMock() - 没有区别
- 使用 Mock()/Stub() 而不是 GroovyMock() - 然后该属性在所有 println 的偶数 Groovy (!!?) 中为 null (!!?)
- 模拟“testEntityMock.prop >>”而不是“testEntityMock.getProp() >>” - 没有区别
【问题讨论】:
-
您可以尝试使用github.com/joke/spock-mockable 来避免必须明确地
open类/属性。 -
此外,如果模拟类不是 Groovy 类,
GroovyMock的行为就像一个简单的 Spock 模拟。这记录在here。所以请不要指望那里有特殊的行为。一个普通的模拟是你想与 Kotlin 类一起使用的。
标签: java kotlin groovy mocking spock