如何在每次测试中更改类的metaClass

时间:2014-12-17 20:04:48

标签: grails integration-testing grails-controller spring-bean expandometaclass

我正在使用ExpandoMetaClass使服务始终在集成测试中返回成功,但我希望有一个实际上失败的测试。

使用ExpandoMetaClass的示例:

static {
        ExpandoMetaClass someService = new ExpandoMetaClass(Object, false)
        someService.accessAnotherSystem = { return 'success' }
        someService.initialize()
        SomeService.metaClass = someService
    }

注意:目前没有为控制器定义服务,但因为它是一个引用名为SomeService的类{spring} someService.accessAnotherSystem()的Spring bean,所以工作正常,即没有def someService控制器。

因此我无法从集成测试中做controller.someService.metaClass.accessAnotherSystem = { return 'failure'}

另请注意:这是Webflow的集成测试。

是否可以为一次测试重置metaClass,或者以某种方式测试我想要的内容?

1 个答案:

答案 0 :(得分:0)

如果测试单独运行,则下面的工作正常,但如果在其之前运行使用SomeService的另一个测试,则会覆盖ExpandoMetaClass。我将为这个问题打开另一个问题。

static {
    ExpandoMetaClass someService = new ExpandoMetaClass(Object, false)
    someService.invokeMethod = { String name, args ->
        def result = 'success'
        if(name.equals('accessAnotherSystem')
        {
            StackTraceUtils.sanitize(new Throwable()).stackTrace.each
            {
                if(it.methodName.equals('method_I_Want_failure')
                {
                    result = 'exception'
                }
            }
            return result
        }

        def validMethod = SomeService.metaClass.getMetaMethod(name, args)
        if (validMethod != null)
        {
            validMethod.invoke(delegate, args)
        }
        else
        {
            SomeService.metaClass.invokeMissingMethod(delegate, name, args)
        }
    }
    someService.initialize()
    SomeService.metaClass = someService
}