On 21 July 2015 at 21:11, Sean LeBlanc <sean.lebl...@icd-tech.com> wrote: > Thanks. I should have mentioned that I would have used that approach, except > that I wasn't able to figure out how to then set that resulting object to > the object I want (which is strongly typed in prod code).
It is true that when using `withTraits()` your new object is no longer of the original type. But I was under the impression that this is for tests, not production. Also, even though the object's class is not C any more, it still implements T, so instead of: C c = new C().withTraits T2 you could use T c = new C().withTraits T2 to see the type checker happy. > > Is there any chance this metaclass behavior is related to this bug? We also > just ran into this one recently, as we started to use more interfaces to > enforce some behaviors we want concrete classes to have. > > https://issues.apache.org/jira/browse/GROOVY-3493 > There are certainly similarities, and traits are implemented as interfaces + helper classes, so I guess there is a chance. Cheers, Dinko > > > On 7/20/15 2:30 AM, Dinko Srkoč wrote: > >> On 17 July 2015 at 19:23, Sean LeBlanc <sean.lebl...@icd-tech.com> wrote: >>> >>> I'm trying to figure out the recommended way to write unit tests for >>> classes >>> that have methods implemented as traits that need to be overwritten with >>> metaclass programming. >> >> If what you needed is just overriding trait's methods, you could do it >> with another trait, without resorting to metaclass fiddling: >> >> trait T { >> def speak() { >> println "trait version" >> } >> } >> >> class C implements T {} >> >> trait T2 { >> def speak() { >> println "another trait" >> } >> } >> >> def c = new C().withTraits T2 >> c.speak() // prints "another trait" >> >> Cheers, >> Dinko >> >>> >>> What I've noticed is that using an instance of the class doesn't seem to >>> work, nor does using the class itself. (Commented out below) >>> >>> It seems that setting is on the trait itself does work, however, this >>> must >>> be done before the first time the implementing class is created, or else >>> setting the metaClass to null on the implementing class is required (also >>> commented out below)? >>> >>> >>> Is there a better way to do this? >>> >>> >>> trait T { >>> def speak() { >>> println "trait version" >>> } >>> } >>> >>> class C implements T { >>> } >>> >>> def c = new C() >>> //c.metaClass.speak = { -> println "meta" } >>> //C.metaClass.speak = { -> println "meta" } >>> >>> c.speak() >>> //C.metaClass = null >>> >>> T.metaClass.speak = { println "meta class version" } >>> def c2 = new C() >>> c2.speak() > >