实例元类更改从实例泄漏到实例?

时间:2012-08-29 12:43:15

标签: grails groovy

我有两个junit单元测试,一个测试函数的成功,另一个测试失败恢复代码。

CUT(Class Under Test)实例在setUp方法中实例化。

在失败测试用例的序言中,我通过覆盖实例的元类中的方法来覆盖其中一个cut的方法来抛出异常:

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

当我理解一个Object(而不是它的静态类)的元编程时,当你实例化一个新的Object时,这个新Object的metaClass不会受到你在旧实例上做的任何元编程的影响,但这就是我所观察到的,因为我在执行成功方案时看到,实际上抛出了用于故障测试用例的cut实例中设置的Runtime Exception。

如果您需要更多详细信息,请告诉我,我只是想确保我没有犯下基本的理论错误。

感谢。

更新

这是为了说明我的测试用例应该如何工作:

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()
        }
    }
}

这几乎按预期工作:

  

创建新的MS实例
  testFailure
  不会做的工作
  创建新的MS实例
  testSuccess
  Doin工作

更新2

顺便说一句,加入

registerMetaClass(MyClass)

到setUp方法,我解决了这个问题,但这只是为了保存静态元类,而不是实例的元类,所以现在我彻底搞糊涂了,因为如上面的例子所示,这应该不重要。 ..?

1 个答案:

答案 0 :(得分:0)

你必须清理CUTs元类

测试

@After
public void tearDown() {
    def remove = GroovySystem.metaClassRegistry.&removeMetaClass
    println "Cleaning CUT"
    remove CUT
    remove CUT1
    remove CUT2
}
相关问题