admin管理员组文章数量:1122846
Groovy 2.5.18 (this is custom extension code for an externally-developed project/product, so I have no control over versions). (This is using JUnit 4.13.2 and Java 17.0.13.)
The output of a failing test run is included in a comment towards the bottom of the code.
My goal is to create a base class with a setProperty
method to intercept attempts to set properties and set a boolean field dirty
to indicate that data needs to be synchronized/pushed. This works with an instance of the base class, captured in setPropertyWithoutInheritance
. However, if I extend the base class with another class it fails with the error groovy.lang.MissingFieldException: No such field: myField for class: tests.Foo
(I have included all of the output in a comment starting on line 54.). Using the direct access operator with this.@"$name"
to actually set the field is exactly what the Groovy docs suggest to set the field within setProperty
.
If I redeclare the myField
field in the subclass, both test cases pass. (Ultimately I want my base class also to have several fields which will be common to the few subclasses to represent several variations of things; having to redeclare all of the common fields in the subclasses takes away some of the benefit of having the base in the first case.)
Eventually I found an [answer][1] to another question which might be the heart of the problem and my ignorance of Java/Groovy: "There is no field inheritance in Groovy nor in Java."
//package tests
import org.junit.Test
import org.junit.runner.JUnitCore
class scratch2 {
@Test
void setPropertyWithoutInheritance() {
Bar b = new Bar()
assert !b.dirty
b.myField = "wow"
assert b.dirty
assert b.myField == "wow"
}
@Test
void setPropertyWithInheritance() {
Foo f = new Foo()
assert !f.dirty
f.myField = "howdy"
assert f.myField == "howdy"
assert f.dirty
}
static void main(String... args) {
JUnitCore.main(new Object(){}.getClass().getEnclosingClass().getName())
}
}
class Bar {
String myField
boolean dirty = false
Bar() {
}
void setProperty(String name, Object value) {
println("Called setProperty for ${name} = value '${value}'")
if (name != "dirty") {
this.@"$name" = value
}
this.@dirty = true
}
}
class Foo extends Bar {
// Uncomment below redeclaration of "myField" in subclass and tests pass
/* Otherwise, Groovy 2.5.18 fails with the following output:
JUnit version 4.13.2
.Called setProperty for myField = value 'wow'
.Called setProperty for myField = value 'howdy'
E
Time: 0.083
There was 1 failure:
1) setPropertyWithInheritance(tests.scratch)
groovy.lang.MissingFieldException: No such field: myField for class: tests.Foo
at groovy.lang.MetaClassImpl.setAttribute(MetaClassImpl.java:2915)
at groovy.lang.MetaClassImpl.setAttribute(MetaClassImpl.java:3832)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectField(ScriptBytecodeAdapter.java:398)
at tests.Bar.setProperty(scratch2.groovy:44)
at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:213)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:496)
at tests.scratch.setPropertyWithInheritance(scratch2.groovy:24)
FAILURES!!!
Tests run: 2, Failures: 1
*/
// String myField
Foo() {
super()
}
}
[1]:
本文标签: propertiesGroovy Fields with inheritance in setPropertyStack Overflow
版权声明:本文标题:properties - Groovy: Fields with inheritance in `setProperty` - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736306279a1932898.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论