Can I override a constructor using metaprogramming limited to a scope in groovy?
I'd like to override the constructor of a class for testing. I can do it like this:
SomeClass.metaClass.constructor = { Map params ->
def instance = BeanUtils.instantiateClass(SomeClass)
instance.apply(params)
instance
}
That works, but I need the new constructor to apply to only some instances. In particular, I'd like to limit the scope of this change to a closure. I tried to make a category:
class SomeClassCategory {
static def constructor(instance, params) { }
开发者_开发问答}
use(SomeClassCategory) {
def x = new SomeClass(params)
}
But that creates a method called constructor
instead of an actual constructor. Is there anyway to specify a constructor in a category? Or can I apply changes to the metaClass of SomeClass only within a block like the use(Category)
construct?
I'd suggest using GMock - http://gmock.org/ - to solve this, especially as you're testing. It provides a way of selectively mocking out methods, and then verifying the results, which I believe is what you need.
I use it myself, and it works quite nicely.
In their documentation, there's an example of mocking a constructor:
def mockFile = mock(File, constructor("/a/path/file.txt"))
mockFile.getName().returns("file.txt")
play {
def file = new File("/a/path/file.txt")
assertEquals "file.txt", file.getName()
}
This, combined maybe with partial mocking, should solve your problem.
精彩评论