[英]Unit testing dynamic class load
对于Java中的动态工厂,我有一个简单的模式(实际上是Groovy,但出于所有目的,我们都可以假定为Java),该模式接收操作并通过从具有相应名称的属性文件中读取该操作来动态加载该特定操作的处理程序。
该模式很简单,只要具有带有以下签名的基本方法即可:
class ReflectionFactory implements BaseFactory {
PropertyReader propertyReader
public ReflectionFactory(PropertyReader reader) {
this.propertyReader = reader
}
Adapter resolveAdapter(String serviceName) {
// TODO: Find service configuration in propertyReader and load via class loader
return defaultAdapter
}
}
该类中的功能尚未实现,我想使用TDD来实现它,也就是说,我想创建一个测试来验证给定serviceName ,它将返回适当类型的类。
将加载该类的代码将类似于:
String className = propertyReader.getProperty(serviceName)
this.class.classLoader.loadClass(className, true, false)
从我的角度来看,我需要“模拟”类加载器,但是显然我不想引入注入类仅仅是为了替换这一行:
this.class.classLoader.loadClass(className, true, false)
有什么方法可以测试是否使用正确的参数调用了classLoader? 换句话说,是否有一种方法可以“模拟”或“替换”类加载器?
理想情况下,我能够做到(伪代码)
when(classLoader.loadClass("serviceName", true, false)).thenReturn(dummyClassInstance)
因此,测试代码如下所示:
void testWhenResolveServiceAndClassPropertyDefinedInstansceIsCreated() {
serviceName = "myService"
when(propertyReader.getPropertyValue("myService")).thenReturn("com.mydomain.adapters.testAdapter")
when(classLoader.loadClass("com.mydomain.adapters.testAdapter", true, false)).thenReturn(testDummy)
def factory = new ReflectionFactory(propertyReader)
def adapter = factory.resolveAdapter(serviceName)
assertNotNull(adapter)
verify(classloader).loadClass("com.mydomain.adapters.testAdapter", true, false)
}
我将Mockito用作模拟框架,但是欢迎任何模拟框架/解决方案
据我所知,我可以提出类似的建议(测试是在spock框架中编写的):
@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')
import spock.lang.*
class Test extends Specification {
def 'test'() {
given:
def propertyReader = GroovyMock(PropertyReader)
def loader = GroovyMock(ClassLoader)
and:
def serviceName = 'service'
def serviceClass = 'service.class'
def adapter = new Adapter()
and:
def factory = new ReflectionFactory()
factory.propertyReader = propertyReader
factory.loader = loader
when:
def ret = factory.resolveAdapter(serviceName)
then:
ret == adapter
1 * propertyReader.findProperty(serviceName) >> serviceClass
1 * loader.loadClass('service.class', true, false) >> adapter
}
}
class ReflectionFactory {
PropertyReader propertyReader
ClassLoader loader = getClass().getClassLoader()
Adapter resolveAdapter(String serviceName) {
def cls = propertyReader.findProperty(serviceName)
loader.loadClass(cls, true, false)
}
}
class PropertyReader {
String findProperty(String name) {
//some logic here
}
}
class Adapter {}
希望它能以某种方式对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.