0

I have two junit unit tests, one that tests success of a function, and another that tests failure recovery code when an exception occurs.

The CUT (Class Under Test) instance is instantiated in the setUp method.

In the failure test case's preamble, i override one of the cut's methods to throw an excetion, by overriding the method in the instance's metaclass:

cut.metaClass.internalWork ={throw new RuntimeException('Failing')}

As I understood metaprogramming of an Object (not its static class), when you instantiate a new Object, the metaClass of this new Object is not affected by any metaprogramming you did on the old instance, but that's what I am observing, because I see when executing my success scenario, that the Runtime Exception that is set up in the cut instance that was used for the failure test case, is actually thrown.

If you need more details plea&se let me know, I just want to make sure that I am not making a fundamental theoretical mistake.

Thanks.

Update

This is to illustrate how my test case should work:

class Cut {
    int fn() {
        internalWork()
        1
    }

    void internalWork() {
        println "Doin work"
    }
}

class WtfTests extends TestSupport {
    @Override
    protected void setUp() {
        println "creating new MS instance"
        cut = new Cut()
    }

    void testSuccess() {
        println "testSuccess"
        cut.fn()
    }

    void testFailure() {
        println "testFailure"
        cut.metaClass.internalWork={->
            println "Won't do work"
            throw new RuntimeException('Failing')
        }
        assert 'Failing'==shouldFail(RuntimeException) {
            cut.fn()
        }
    }
}

And this pretty much works as expected:

creating new MS instance
testFailure
Won't do work
creating new MS instance
testSuccess
Doin work

Update 2

By the way, by adding

registerMetaClass(MyClass)

to the setUp method, I solved the issue, but this is only supposed to save the static metaclass, not the instance's metaclass, so now I'm thoroughly confused, because as shown in my example above, this should not matter... ?

4

1 回答 1

0

您必须清理 CUT 元类

测试

@After
public void tearDown() {
    def remove = GroovySystem.metaClassRegistry.&removeMetaClass
    println "Cleaning CUT"
    remove CUT
    remove CUT1
    remove CUT2
}
于 2012-08-29T12:54:21.483 回答