在 Spock 中测试抽象或具体 class 的 属性 访问
Test for property access of an abstract or concrete class in Spock
当我使用 getter/setter 对模拟抽象或具体 class 然后访问 属性 时,相应的 getter/setter 永远不会被调用。但是,如果 Mock
是为接口创建的,这就可以正常工作。在下面的代码中,有 3 组,每组两个测试(一组测试 getter,另一组测试 setter),除了它们模拟的内容外,它们是相同的。第一套工作正常,因为他们正在界面上进行测试,但接下来的两套没有:
import spock.lang.Specification
interface Foo {
public String getProp();
public void setProp(String val);
}
abstract class FooBase implements Foo {
public abstract String getProp();
public abstract void setProp(String val);
}
class FooImpl extends FooBase {
public String getProp() {
println('Foo.getProp')
return null
}
public void setProp(String val) {
println('Foo.setProp')
}
}
class TestPropertyAccess extends Specification {
def 'test setter on interface'() {
given:
def foo = Mock(Foo)
when:
foo.prop = 'val'
then:
1 * foo.setProp(_)
}
def 'test getter on interface'() {
given:
def foo = Mock(Foo)
when:
foo.prop
then:
1 * foo.getProp()
}
def 'test setter on abstract'() {
given:
def foo = Mock(FooBase)
when:
foo.prop = 'val'
//foo.setProp('val')
then:
1 * foo.setProp(_)
//1 * foo.setProperty('prop', 'val')
}
def 'test getter on abstract'() {
given:
def foo = Mock(FooBase)
when:
foo.prop
//foo.getProp()
then:
1 * foo.getProp()
//1 * foo.getProperty('prop')
}
def 'test setter on concrete'() {
given:
def foo = Mock(FooImpl)
when:
foo.prop = 'val'
//foo.setProp('val')
then:
1 * foo.setProp(_)
//1 * foo.setProperty('prop', 'val')
}
def 'test getter on concrete'() {
given:
def foo = Mock(FooImpl)
when:
foo.prop
//foo.getProp()
then:
1 * foo.getProp()
//1 * foo.getProperty('prop')
}
}
如果我用相应的 getter/setter 替换 属性 访问,或者如果我测试通用 getProperty
/setProperty
,我可以使失败的测试工作。
我是不是遗漏了什么或者这可能是 spock 错误?
抓得好!鉴于
这一事实,我会认为这是一个 Spock 错误
- 当从常规 Groovy 程序调用时,如果您添加一个真正的 属性 并设置 setter 和getter明白了,
- 测试在 Spock 1.3 和 2.0 预览版中表现不同(getter 测试有效,只有 setter 测试失败)。
可能在编译期间从 Spock DSL 生成实际代码的 AST 转换中出现了问题。
我刚刚为您打开了 bug ticket #1158。
更新: 其实我只是注意到,如果应用程序 类 在 Java 中实现,它会按预期工作,但当然你不能使用方法 {get|set}Property
因为它们只定义在 GroovyObject
s.
2020-10-28 更新:该问题已在 Spock master 中修复,并将成为 Spock 2.0 的一部分。请参阅问题 #1158。
当我使用 getter/setter 对模拟抽象或具体 class 然后访问 属性 时,相应的 getter/setter 永远不会被调用。但是,如果 Mock
是为接口创建的,这就可以正常工作。在下面的代码中,有 3 组,每组两个测试(一组测试 getter,另一组测试 setter),除了它们模拟的内容外,它们是相同的。第一套工作正常,因为他们正在界面上进行测试,但接下来的两套没有:
import spock.lang.Specification
interface Foo {
public String getProp();
public void setProp(String val);
}
abstract class FooBase implements Foo {
public abstract String getProp();
public abstract void setProp(String val);
}
class FooImpl extends FooBase {
public String getProp() {
println('Foo.getProp')
return null
}
public void setProp(String val) {
println('Foo.setProp')
}
}
class TestPropertyAccess extends Specification {
def 'test setter on interface'() {
given:
def foo = Mock(Foo)
when:
foo.prop = 'val'
then:
1 * foo.setProp(_)
}
def 'test getter on interface'() {
given:
def foo = Mock(Foo)
when:
foo.prop
then:
1 * foo.getProp()
}
def 'test setter on abstract'() {
given:
def foo = Mock(FooBase)
when:
foo.prop = 'val'
//foo.setProp('val')
then:
1 * foo.setProp(_)
//1 * foo.setProperty('prop', 'val')
}
def 'test getter on abstract'() {
given:
def foo = Mock(FooBase)
when:
foo.prop
//foo.getProp()
then:
1 * foo.getProp()
//1 * foo.getProperty('prop')
}
def 'test setter on concrete'() {
given:
def foo = Mock(FooImpl)
when:
foo.prop = 'val'
//foo.setProp('val')
then:
1 * foo.setProp(_)
//1 * foo.setProperty('prop', 'val')
}
def 'test getter on concrete'() {
given:
def foo = Mock(FooImpl)
when:
foo.prop
//foo.getProp()
then:
1 * foo.getProp()
//1 * foo.getProperty('prop')
}
}
如果我用相应的 getter/setter 替换 属性 访问,或者如果我测试通用 getProperty
/setProperty
,我可以使失败的测试工作。
我是不是遗漏了什么或者这可能是 spock 错误?
抓得好!鉴于
这一事实,我会认为这是一个 Spock 错误- 当从常规 Groovy 程序调用时,如果您添加一个真正的 属性 并设置 setter 和getter明白了,
- 测试在 Spock 1.3 和 2.0 预览版中表现不同(getter 测试有效,只有 setter 测试失败)。
可能在编译期间从 Spock DSL 生成实际代码的 AST 转换中出现了问题。
我刚刚为您打开了 bug ticket #1158。
更新: 其实我只是注意到,如果应用程序 类 在 Java 中实现,它会按预期工作,但当然你不能使用方法 {get|set}Property
因为它们只定义在 GroovyObject
s.
2020-10-28 更新:该问题已在 Spock master 中修复,并将成为 Spock 2.0 的一部分。请参阅问题 #1158。