Grails:将插件类导入_Events.groovy



我创建了一个Grails插件,它添加了一个自定义测试类型类(扩展了GrailsTestTypeSupport)和自定义测试结果类(扩展GrailsTestTypeResult),以支持我在test-app脚本的other阶段运行的自定义测试类型。在我的本地机器上测试这一点进展顺利,但。。。

当我打包插件在我的应用程序中使用时,我们的CI服务器(Jenkins)上的测试正在爆炸。这是詹金斯吐出的错误:

unable to resolve class CustomTestResult  @ line 58, column 9.
new CustomTestResult(tests.size() - failed, failed)

看来我不能简单地将这些类import_Events.groovy,而且这些类不在类路径上。但如果我能弄清楚如何将它们放到类路径上,我会很生气的。以下是我迄今为止(在_Events.groovy中)拥有的内容:

import java.lang.reflect.Constructor
eventAllTestsStart = {
if (!otherTests) otherTests = []
loadCustomTestResult()
otherTests << createCustomTestType()
}
private def createCustomTestType(String name = 'js', String relativeSourcePath = 'js') {
ClassLoader parent = getClass().getClassLoader()
GroovyClassLoader loader = new GroovyClassLoader(parent)
Class customTestTypeClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestType.groovy"))
Constructor customTestTypeConstructor = customTestTypeClass.getConstructor(String, String)
def customTestType = customTestTypeConstructor.newInstance(name, relativeSourcePath)
customTestType
}
private def loadCustomTestResult() {
ClassLoader parent = getClass().getClassLoader()
GroovyClassLoader loader = new GroovyClassLoader(parent)
Class customTestResultClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestResult.groovy"))
}

当前:CustomTestResult仅从CustomTestType中引用。据我所知,_Events.groovy正在加载CustomTestType,但它失败了,因为它坚持CustomTestResult不在类路径上。

暂且不谈,让插件提供的类进入测试周期的类路径会有这么多开销,这似乎很疯狂。。。我不太确定我在哪里被绊倒了。任何帮助或建议都将不胜感激。

您是否尝试过简单地通过ClassLoader加载有问题的类,该ClassLoader可通过_Events.groovy中的classLoader变量访问?

Class customTestTypeClass = classLoader.loadClass('custom.test.CustomTestType')
// use nice groovy overloading of Class.newInstance
return customTestTypeClass.newInstance(name, relativeSourcePath)

eventAllTestsStart的过程中,您应该足够晚才能使其生效。

@Ian Roberts的回答让我大致指向了正确的方向,并结合这个grails-cucumber插件中的_Events.groovy脚本,我成功地实现了这个解决方案:

首先,_Events.groovy变成了这个:

eventAllTestsStart = { if (!otherTests) otherTests = [] }
eventTestPhasesStart = { phases ->
if (!phases.contains('other')) { return }
// classLoader.loadClass business per Ian Roberts:
otherTests << classLoader.loadClass('custom.test.CustomTestType').newInstance('js', 'js')
}

这比我在这个线程开始时的可读性要好得多。但是:我处于大致相同的位置:当我的ClassNotFoundException试图创建custom.test. CustomTestResult的实例时,它从在_Events.groovy中抛出变成了在CustomTestType中抛出。因此,在CustomTestType中,我添加了以下方法:

private GrailsTestTypeResult createResult(passed, failed) {
try {
return new customTestResult(passed, failed)
} catch(ClassNotFoundException cnf) {
Class customTestResult = buildBinding.classLoader.loadClass('custom.test.CustomTestResult')
return customTestResult.newInstance(passed, failed)
}
}

所以伊恩是对的,因为classLoader拯救了我——我只是在两个地方需要它的魔力。

最新更新