I'm having trouble with replacing and then restoring a method using metaClass, to override behaviour for a test. Any help much appreciated.
In one of my tests, I inject: Foo.metaClass.myBusinessLogic = { /* record stuff here */ }
That works well for intercepting the (expensive) call and recording it. But everything in the test suite then subsequently fails because the method is now a no-op! I've been trying to restore the original method in the tearDown.
--- My attempts have involved code like that below. But for each of my attempts, it keeps writing out "replacement".
class ReplacingAndRestoringMetaMethod { public static void main(String[] args) { def origMethod = Foo.metaClass.myBusinessLogic //def origMethod2 = Foo.metaClass.getMetaMethod("myBusinessLogic", new Object[0])
> I'm having trouble with replacing and then restoring a method using > metaClass, to override behaviour for a test. Any help much appreciated.
> In one of my tests, I inject: > Foo.metaClass.myBusinessLogic = { /* record stuff here */ }
> That works well for intercepting the (expensive) call and recording it. > But everything in the test suite then subsequently fails because the method > is now a no-op! I've been trying to restore the original method in the > tearDown.
> --- > My attempts have involved code like that below. But for each of my > attempts, it keeps writing out "replacement".
> class ReplacingAndRestoringMetaMetho**d { > public static void main(String[] args) { > def origMethod = Foo.metaClass.myBusinessLogic > //def origMethod2 = Foo.metaClass.getMetaMethod("**myBusinessLogic", > new Object[0])
It was made a bit more complicated by my app-under-test being multi-threaded, so I had to inject a thread factory that wraps each Runnable.run in a `use (FooTestCategory)`. Luckily I could inject that thread factory using another test category :-)
> On Fri, Dec 2, 2011 at 4:29 PM, Aled Sage <aled.s...@cloudsoftcorp.com > <mailto:aled.s...@cloudsoftcorp.com>> wrote:
> Hi,
> I'm having trouble with replacing and then restoring a method > using metaClass, to override behaviour for a test. Any help much > appreciated.
> In one of my tests, I inject: > Foo.metaClass.myBusinessLogic = { /* record stuff here */ }
> That works well for intercepting the (expensive) call and > recording it. But everything in the test suite then subsequently > fails because the method is now a no-op! I've been trying to > restore the original method in the tearDown.
> --- > My attempts have involved code like that below. But for each of my > attempts, it keeps writing out "replacement".
> class ReplacingAndRestoringMetaMethod { > public static void main(String[] args) { > def origMethod = Foo.metaClass.myBusinessLogic > //def origMethod2 = > Foo.metaClass.getMetaMethod("myBusinessLogic", new Object[0])
On 2 December 2011 19:29, Aled Sage <aled.s...@cloudsoftcorp.com> wrote:
> Hi,
> I'm having trouble with replacing and then restoring a method using > metaClass, to override behaviour for a test. Any help much appreciated.
> In one of my tests, I inject: > Foo.metaClass.myBusinessLogic = { /* record stuff here */ }
> That works well for intercepting the (expensive) call and recording it. But > everything in the test suite then subsequently fails because the method is > now a no-op! I've been trying to restore the original method in the > tearDown.
In order to restore the original method you might try putting this in the tearDown:
It looks like you have to have an instance before using categories. What do you do if you don't have an instance, for example, I am replacing the method static method bar in class Foo:
Foo.metaClass.'static'.bar = { "Mocked" }
What's the best way restore bar to it's original state? Or is there a better solution (I hope).